Изменить заголовок навигации для средства выбора в SwiftUI
Я хотел бы установить заголовок навигации, когда пользователь выбрал какой-либо параметр в Picker
Вот моя модель выбора:
enum AppIcon: CaseIterable, Identifiable {
var id: Self {
return self
}
case `default`
case ethereum
case litecoin
var name: String {
switch self {
case .default:
return "Bitcoin"
case .ethereum:
return "Ethereum"
case .litecoin:
return "Litecoin"
}
}
}
и вот мой взгляд
struct ContentView: View {
@State var icon: AppIcon = .default
var body: some View {
NavigationView {
Form {
Section {
Picker(selection: $icon, label: Text("Icon")) {
ForEach(AppIcon.allCases) { icon in
Text(icon.name).tag(icon)
}
}
}
}
.navigationBarTitle("Appearance")
}
}
}
Я хочу добиться такого поведения:
но я попытался поставить .navigationBarTitle("Title")
после любой закрывающей скобки, и это не сработает.
2 ответа
Я попытался решить проблему. Проверьте решение, приведенное ниже.
struct ContentView: View {
@State var icon: AppIcon = .default
var body: some View {
NavigationView {
Form {
Section {
Picker(selection: $icon, label: Text("Icon")) {
ForEach(AppIcon.allCases) { icon in
Text(icon.name).tag(icon)
}
.navigationBarTitle("Title") // for picker navigation title
}
.navigationBarTitle("Appearance")
}
}
}
}
}
Хитрость заключается в том, чтобы создать новое представление через NavigationLink.
Так покажи код!!!
Это основное представление с формой в NavigationView.
struct ContentView: View {
@ObservedObject private var viewModel: ViewModel
init() {
self.viewModel = ViewModel()
}
var body: some View {
NavigationView {
Form {
PickerView(viewModel: viewModel)
}
.navigationTitle("Appearance")
}
}
}
Я использовал ViewModel для хранения данных, которые представляет представление. Думаю можно и без.
class ViewModel: ObservableObject {
@Published var icon: AppIcon = .default
}
В этой структуре определяется фактический сборщик. Он моделируется списком.
struct PickerView: View {
@ObservedObject private var viewModel: ViewModel
@State var presentSelectionView = false // for getting back to main menu
init(viewModel: ViewModel) {
self.viewModel = viewModel
}
var body: some View {
NavigationLink(isActive: $presentSelectionView) {
picker()
.navigationTitle("Title")
.navigationBarTitleDisplayMode(.large)
} label: {
HStack {
Text("Icon")
Spacer()
Text(viewModel.icon.name)
.foregroundColor(Color.gray)
}
}
}
private func picker() -> some View {
List {
ForEach(AppIcon.allCases, id: \.self) { icon in
HStack {
Text(icon.name)
Spacer()
if icon == viewModel.icon {
Image(systemName: "checkmark")
.foregroundColor(.accentColor) // or any other color
}
}
.contentShape(Rectangle()) // whole line is tappable
.onTapGesture {
self.viewModel.icon = icon
self.presentSelectionView = false
}
}
}
.listStyle(GroupedListStyle())
}
}
Я использовал перечисление, как оно было дано в вопросе.
В итоге это выглядит так:
Я сделал это с XCode 13.1 и iOS 15.2.