简体   繁体   English

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

[英]Navigation bar only have background when scroll

I am trying to implement a detail view which is linked from a navigation view.我正在尝试实现从导航视图链接的详细视图。 In this detail view, there is a default nav bar on top with a back button.在此详细视图中,顶部有一个默认导航栏,带有一个后退按钮。 But the bar only show some color when I scroll up.但是当我向上滚动时,该栏只显示一些颜色。 I have no idea why.我不知道为什么。

No Scroll:无滚动: 透明导航栏

Scroll:滚动: 有背景颜色

Initially, the nav bar doesn't have background either when it's scrolling or not.最初,导航栏在滚动或不滚动时都没有背景。 So I created an init() method for setting up the style.所以我创建了一个 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
    }
  }

The Body View is a Navigation View on the outside and scroll view inside. Body View 是外部的导航视图和内部的滚动视图。 ** For anyone wonder why I set the navbar to hidden in the VStack, is because if I don't hide it, there would be some huge space above the image. ** 有人想知道为什么我将导航栏设置为隐藏在 VStack 中,是因为如果我不隐藏它,图像上方会有一些巨大的空间。 (I have no idea why) (我不知道为什么) 巨大的空间,不知道是什么原因造成的

** Updated Code ** I updated my code which use the Opaque background. ** 更新代码 ** 我更新了使用不透明背景的代码。 But it seems like none of those config are visible.但似乎这些配置都不可见。

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())
}

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

*** Solution *** It turns out I have to put the configurations code of the nav bar in the parent view. ***解决方案***原来我必须将导航栏的配置代码放在父视图中。 During init().在 init() 期间。 Can anyone explain why this on the parent view?谁能在父视图上解释为什么会这样? Or if I want different style in parent and child what should I do?或者,如果我想要父母和孩子的风格不同,我该怎么办?

    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

}

父视图

        navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
        navigationController?.navigationBar.shadowImage = UIImage()

use this code in viewWillAppear在 viewWillAppear 中使用此代码

Use my extension:使用我的扩展:

extension UIViewController {
func configureNavigationBar(largeTitleColor: UIColor, backgoundColor: UIColor, tintColor: UIColor, title: String, preferredLargeTitle: Bool) {
if #available(iOS 13.0, *) {
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithOpaqueBackground()
navBarAppearance.largeTitleTextAttributes = [.foregroundColor: largeTitleColor]
navBarAppearance.titleTextAttributes = [.foregroundColor: largeTitleColor]
navBarAppearance.backgroundColor = backgoundColor
navigationController?.navigationBar.standardAppearance = navBarAppearance
navigationController?.navigationBar.compactAppearance = navBarAppearance
navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance

navigationController?.navigationBar.prefersLargeTitles = preferredLargeTitle
navigationController?.navigationBar.isTranslucent = false
navigationController?.navigationBar.tintColor = tintColor
navigationItem.title = title

} else {
// Fallback on earlier versions
navigationController?.navigationBar.barTintColor = backgoundColor
navigationController?.navigationBar.tintColor = tintColor
navigationController?.navigationBar.isTranslucent = false
navigationItem.title = title
  }
 }
}

call it in viewDidAppear or viewDidLoad, in your case set background to clear... How to use:在 viewDidAppear 或 viewDidLoad 中调用它,在您的情况下将背景设置为清除... 如何使用:

configureNavigationBar(largeTitleColor: .yourColor, backgoundColor: .yourColor, tintColor: .yourColor, title: "YourTitle", preferredLargeTitle: false)

You need opaque appearance, because default one means system-selected-by-design which is changed from version to version.您需要不透明的外观,因为default的一种表示system-selected-by-design ,它从一个版本更改为另一个版本。

演示

    let navBarAppearance = UINavigationBarAppearance()
    navBarAppearance.configureWithOpaqueBackground()
    UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance

Tested with Xcode 13.3 / iOS 15.4 (in ContentView.init)使用 Xcode 13.3 / iOS 15.4 测试(在 ContentView.init 中)

Note: onAppear is too late to inject above code, the appearance settings are applied on objects created after it, and onAppear is called after NavigationView created.注意:onAppear 来不及注入上面的代码,外观设置应用在它之后创建的对象上,并且在 NavigationView 创建之后调用 onAppear。 So use it either in init, or anywhere else, but before view created.因此,在 init 或其他任何地方使用它,但在创建视图之前。

This worked for me -这对我有用 -

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Swift & 导航:导航栏在滚动视图时更改其背景颜色 - Swift & Navigation : Navigation Bar changes its background color when scroll the view initWithNibName:我没有滚动并且没有导航栏? - initWithNibName : I have no scroll and no navigation bar? 自定义导航栏与背景 - Custom Navigation Bar With Background 隐藏导航栏时,使用带有水平滚动的CollectionView的interactivepopgesturerecognizer - Use interactivepopgesturerecognizer with CollectionView with horizontal scroll when navigation bar is hidden 当以编程方式约束时,如何在向下滚动时隐藏导航栏? - How to hide the navigation bar as scroll down, when constraints are programmatically? 如何隐藏滚动条上的导航栏(屏幕顶部除外) - How to hide navigation bar on scroll except when at the top of the screen 向下滚动时如何隐藏导航栏? - How to hide navigation bar when I scroll down? 当应用程序处于后台状态时,单击通知时导航栏消失 - Navigation bar disappear when click on notification when app is in background state 不推荐使用UIBarMetricsLandscapePhone时设置导航栏背景图像iOS 8 - Setting Navigation bar background image when UIBarMetricsLandscapePhone is deprecated iOS 8 在2个VC之间传输时,导航栏的背景色存在问题 - Having issues with the navigation bar background color when transferring between 2 VCs
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM