如何在 SwiftUI 上的导航栏中的标题下添加分段选择器?

问题描述 投票:0回答:1

我正在尝试使用 SwiftUI 在标题下的导航栏中添加分段选择器。 我尝试过使用工具栏,但它显示在顶部而不是标题下方。

如何在 SwiftUI 中达到下图所示的效果?

Screenshot from the App Store leaderboard.

这是我尝试过的方法,但不起作用。


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)
    }
}
swift swiftui navigationbar picker
1个回答
0
投票

我刚刚在 YouTube 上的 Kavsoft 视频中观看了类似的内容,了解如何制作粘性标题,这是一个超级有趣的主题,并且没有默认的方法来做到这一点

视频中有2个重点:

  1. 他隐藏了默认的工具栏背景(带有分隔线的薄材料);
  2. 他将视图添加到安全区域并带回工具栏背景

我还将在这里列出各个阶段:

  1. 安全区域顶部插图内添加分段选取器,即使在滚动时也可以使用
    .safeAreaInset(edge: .top)
    修饰符将其固定到顶部。

  1. 为分段选取器(安全区域插入内容)提供类似于原始工具栏背景的背景,例如:
.padding(.bottom)
.background {
    Rectangle()
        .fill(.ultraThinMaterial)
        .ignoresSafeArea()
}
  1. 删除默认工具栏背景(使用
    .toolbarBackgroundVisibility(.hidden, for: .navigationBar)
    .toolbarBackground(.hidden, for: .navigationBar)

代码实现:

我用代码为你实现了它:


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()
                        }
                }
            }
            .toolbarBackground(.hidden, for: .navigationBar)
            
        }
        
        
    }
}

#Preview {
    SticktoHeader()
}
© www.soinside.com 2019 - 2024. All rights reserved.