I'm trying to add a segmented picker in the NavigationBar under the title with SwiftUI. I've tried with the toolbar, but it was show on the top and not under the title.
How can I achieve the result like the image below in SwiftUI?
This is what I have tried but doesn't work.
struct ExampleView: View {
@State private var selectedTab: String = "tab1"
var body: some View {
VStack {
Picker("Mode", selection: $selectedTab) {
Text("tab1").tag("tab1")
Text("tab2").tag("tab2")
Text("tab3").tag("tab3")
}
.pickerStyle(.segmented)
.padding([.horizontal, .top])
Form {
switch selectedTab {
case "tab1":
TabOneView()
case "tab2":
TabTwoView()
case "tab3":
TabThreeView()
default:
TabOneView()
}
}
}
.navigationTitle("Title")
.navigationBarTitleDisplayMode(.inline)
}
}
I've just been watching a similar thing in one of Kavsoft's videos on YouTube on how to make a sticky header, it's a super interesting topic and there is no default way to do it.
There's 2 important points in the video:
I will also list the stages here:
.safeAreaInset(edge: .top)
modifier..padding(.bottom)
.background {
Rectangle()
.fill(.ultraThinMaterial)
.ignoresSafeArea()
}
Edit!!!
Instead of trying to emulate the toolbar background, you can access it with .background(.bar)
.
Thanks to @BenzyNeez for this suggestion.
.toolbarBackgroundVisibility(.hidden, for: .navigationBar)
or .toolbarBackground(.hidden, for: .navigationBar)
.I implemented it in code for you:
import SwiftUI
enum Option {
case a, b
var text: String {
switch self {
case .a: "App gratuite"
case .b: "App a pagamento"
}
}
}
struct SticktoHeader: View {
@State private var tab = Option.a
var body: some View {
NavigationStack {
// List stuff
List(0..<50) { n in
Text("Item \(n)")
}
.navigationTitle("Classifiche")
.toolbar {
// Add a default toolbar
ToolbarItem(placement: .topBarTrailing) {
Button("Tutte le app") { }
}
}
// NEW 1: Add safe area inset
.safeAreaInset(edge: .top) {
Picker("Pick tab", selection: $tab) {
Text(Option.a.text)
.tag(Option.a)
Text(Option.b.text)
.tag(Option.b)
}
.padding(.horizontal)
.padding(.bottom)
.pickerStyle(.segmented)
//.background {
//Rectangle()
//.fill(.ultraThinMaterial)
//.ignoresSafeArea()
//.overlay(alignment: .bottom) {
//Divider()
//}
//}
.background(.bar) // Thanks @BenzyKneez
}
.toolbarBackground(.hidden, for: .navigationBar)
}
}
}
#Preview {
SticktoHeader()
}