Reputation: 14329
I'd like to set a navigation title when an user selected some option in Picker
Here is my selection model:
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"
}
}
}
and here is my view
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")
}
}
}
I want to get that behavior:
but I tried to put .navigationBarTitle("Title")
after any close bracket and it doesn't work.
Upvotes: 15
Views: 6811
Reputation: 839
The trick is to create a new view via a NavigationLink.
So show us the code!!!
This is the main View with a Form in a NavigationView.
struct ContentView: View {
@ObservedObject private var viewModel: ViewModel
init() {
self.viewModel = ViewModel()
}
var body: some View {
NavigationView {
Form {
PickerView(viewModel: viewModel)
}
.navigationTitle("Appearance")
}
}
}
I used a ViewModel to hold the data which the View is presenting. I guess it is possible to do it without.
class ViewModel: ObservableObject {
@Published var icon: AppIcon = .default
}
In this struct the actual picker is defined. It is simulated with a list.
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())
}
}
I used the enum like it was given in the question.
In the end it looks like this:
I have done this with XCode 13.1 and iOS 15.2
Upvotes: 1
Reputation: 658
I have tried to solve issue.
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")
}
}
}
}
}
Upvotes: 0