导航栏只有滚动时才有背景

Jon*_*Liu 8 scroll transparent ios swift swiftui

我正在尝试实现从导航视图链接的详细视图。在此详细视图中,顶部有一个带有后退按钮的默认导航栏。 但当我向上滚动时,该栏仅显示一些颜色。我不知道为什么。

无滚动:透明导航栏

滚动:有背景颜色

最初,导航栏在滚动或不滚动时都没有背景。所以我创建了一个 init() 方法来设置样式。

 init(fruit: Fruit) {
    self.fruit = fruit
    if #available(iOS 15.0, *) {
        let navigationBarAppearance = UINavigationBarAppearance()
        navigationBarAppearance.configureWithDefaultBackground()
        
        UINavigationBar.appearance().standardAppearance = navigationBarAppearance
        UINavigationBar.appearance().compactAppearance = navigationBarAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = navigationBarAppearance
    }
  }
Run Code Online (Sandbox Code Playgroud)

主体视图是外部的导航视图和内部的滚动视图。** 对于任何人来说,为什么我将导航栏设置为隐藏在 VStack 中,是因为如果我不隐藏它,图像上方将会有一些巨大的空间。(我不知道为什么) 巨大的空间,不知道是什么造成的

** 更新的代码 ** 我更新了使用不透明背景的代码。但似乎这些配置都不可见。

init(fruit: Fruit) {
    self.fruit = fruit
    let navBarAppearance = UINavigationBarAppearance()
    navBarAppearance.configureWithOpaqueBackground()
    UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
    UINavigationBar.appearance().standardAppearance = navBarAppearance
}

var body: some View {
    NavigationView {
        ScrollView(.vertical, showsIndicators: false) {
            VStack(alignment: .center, spacing: 20) {
                // HEADER
                FruitHeaderView(fruit: fruit)
                
                VStack(alignment: .leading, spacing: 20) {
                    // TITLE
                    Text(fruit.title)
                        .font(.largeTitle)
                        .fontWeight(.heavy)
                        .foregroundColor(fruit.gradientColors[1])
                    
                    
                } //: VSTACK
                .padding(.horizontal, 20)
                .frame(maxWidth: 640, alignment: .center)
            } //: VSTACK
            .navigationBarHidden(true)
        } //: SCROLL
        .edgesIgnoringSafeArea(.top)
    } //: NAVIGATION
    .navigationBarTitle(fruit.title, displayMode: .inline)
    .navigationViewStyle(StackNavigationViewStyle())
}
Run Code Online (Sandbox Code Playgroud)

在初始化期间配置导航栏,但在滚动之前仍然看不到背景

*** 解决方案*** 原来我必须将导航栏的配置代码放在父视图中。在 init() 期间。 谁能解释一下为什么在父母的观点上会这样?或者如果我想要父母和孩子有不同的风格我该怎么办?

    init() {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
         UINavigationBar.appearance().standardAppearance = navBarAppearance
    }

var body: some View {
    NavigationView {
        List {
            ForEach(fruits.shuffled()) { item in
                NavigationLink {
                    FruitDetailView(fruit: item)
                } label: {
                    FruitRowView(fruit: item)
                        .padding(.vertical, 4)
                }
            }
        }
        .listStyle(.plain)
        .navigationTitle("Fruits")
    } //: NAVIGATION

}
Run Code Online (Sandbox Code Playgroud)

父视图

Pra*_*wad 5

这对我有用 -

func changeNavBar(navigationBar: UINavigationBar, to color: UIColor) {
            let appearance = UINavigationBarAppearance()
            appearance.configureWithOpaqueBackground()
            appearance.backgroundColor = color
            navigationBar.standardAppearance = appearance;
            navigationBar.scrollEdgeAppearance = navigationBar.standardAppearance
}
Run Code Online (Sandbox Code Playgroud)

  • 这一行对我有用: navigationBar.scrollEdgeAppearance = navigationBar.standardAppearance 在我的实例中,我在自定义 NavigationController 类中使用此代码...您将需要对 navigationController 的引用才能访问其上的 .navigationBar 。 (2认同)

Asp*_*eri 1

您需要不透明的外观,因为default这意味着system-selected-by-design它会随着版本的不同而改变。

演示

    let navBarAppearance = UINavigationBarAppearance()
    navBarAppearance.configureWithOpaqueBackground()
    UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
Run Code Online (Sandbox Code Playgroud)

使用 Xcode 13.3 / iOS 15.4 进行测试(在 ContentView.init 中)

注意:onAppear 来不及注入上面的代码,外观设置应用于在其之后创建的对象,并且 onAppear 在 NavigationView 创建后调用。因此,可以在 init 中或其他任何地方使用它,但要在创建视图之前。