【问题标题】:iOS 15 Navigation Bar TransparentiOS 15 导航栏透明
【发布时间】:2021-11-05 17:22:26
【问题描述】:

我的 iOS 应用为 UI 使用故事板,并为导航栏的背景颜色使用自定义色调。

我在 Xcode 13 beta 5 上测试了我的应用,导航栏为“白色”,导航栏上的文字不可见。

https://developer.apple.com/forums/thread/682420 的苹果开发者论坛中声明 “在 iOS 15 中,UIKit 已将默认情况下会产生透明背景的 scrollEdgeAppearance 的使用扩展到所有导航栏。”要恢复旧外观,您必须采用新的 UINavigationBar 外观 API

我将以下代码(来自上面的链接)添加到 App Delegate "application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions":

        if #available(iOS 13, *) {
            let navigationController = UINavigationController(navigationBarClass: nil, toolbarClass: nil)
            let navigationBar = navigationController.navigationBar
            let appearance = UINavigationBarAppearance()
            appearance.configureWithOpaqueBackground()
            appearance.backgroundColor = UIColor(red: 0.0/255.0, green: 125/255.0, blue: 0.0/255.0, alpha: 1.0)
            navigationBar.standardAppearance = appearance;
            navigationBar.scrollEdgeAppearance = navigationBar.standardAppearance
            navigationBar.isTranslucent = false
        }

这并不能解决问题。我仍然在故事板编辑器中为导航栏设置了自定义色调。我需要删除自定义色调还是我实现的外观 API 错误?

【问题讨论】:

  • 您正在代码 sn-p 中创建 UINavigationController 的新实例。你在用这个实例做什么?只是一个疯狂的猜测:我认为您正在寻找类似 @​​987654324@ 的东西,但老实说我不熟悉新的 iOS 15 API。

标签: swift uinavigationcontroller ios15 xcode13


【解决方案1】:

斯威夫特

// White non-transucent navigatio bar, supports dark appearance
if #available(iOS 15, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    UINavigationBar.appearance().standardAppearance = appearance
    UINavigationBar.appearance().scrollEdgeAppearance = appearance
}

目标-c

if (@available(iOS 15.0, *)) {
    UINavigationBarAppearance *navBarAppearance = [[UINavigationBarAppearance alloc] init];
  navBarAppearance.backgroundColor = [UIColor redColor];
    [navBarAppearance configureWithOpaqueBackground];
    [UINavigationBar appearance].standardAppearance = navBarAppearance;
    [UINavigationBar appearance].scrollEdgeAppearance = navBarAppearance;
}

【讨论】:

  • 谢谢。不知道为什么其他答案有这么多赞成票,但这给出了正确的“Xcode 13 前”导航栏行为。如果您愿意,还可以使用 configureWithDefaultBackground() 来保留旧的透明效果。
  • 我有多个导航控制器,有些颜色不同。我注意到,当我导航到它们时,颜色变化并没有立即发生,并且颜色仅在我第二次导航时才正确。我该如何纠正呢?
  • 我想通了。为了给多个导航控制器应用不同的颜色,我分配了 self.navigationController.navigationBar 的 standardAppearancescrollEdgeAppearance 而不是 UINavigationBar.appearance()。我确实在我的 appDelegate 中修改了 UINavigationBar.appearance(),但这是我打算设置的一般默认值。
  • 我的标题部分显示了我在应用程序中设置的颜色,但在 iOS 15 中的某些屏幕上显示失败。菜单栏也没有关闭
  • 如何在 iOS 15 中显示相同的标题颜色?
【解决方案2】:

无需更改情节提要中的任何内容。 这是添加到 App Delegate application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions 时最终奏效的解决方案:

//Fix Nav Bar tint issue in iOS 15.0 or later - is transparent w/o code below
if #available(iOS 15, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    appearance.titleTextAttributes = [.foregroundColor: UIColor.white]
    appearance.backgroundColor = UIColor(red: 0.0/255.0, green: 125/255.0, blue: 0.0/255.0, alpha: 1.0)
    UINavigationBar.appearance().standardAppearance = appearance
    UINavigationBar.appearance().scrollEdgeAppearance = appearance
}

请注意,如果未指定此属性,则必须将标题文本属性设置为“白色”,因为标题文本默认为黑色。

另请注意,这仅适用于 iOS 15.0 或更高版本。它不适用于早期版本,因为故事板导航栏自定义色调是默认行为。

【讨论】:

  • 我认为您应该将 navigationBar.standardAppearance = appearance; 替换为 UINavigationBar.appearance().standardAppearance = appearance
  • 是的,你是对的 - 发布后注意到这一点。
  • 以上更新以反映@IluSioN 的更正
  • 这段代码放在哪里?
  • 我在App Delegate中添加了application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions
【解决方案3】:

如果有人需要G 的Objective C 版本。史蒂夫的回答

if (@available(iOS 15, *)){
        UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
        [appearance configureWithOpaqueBackground];
        appearance.titleTextAttributes = @{NSForegroundColorAttributeName : UIColor.whiteColor};
        appearance.backgroundColor = [UIColor colorWithRed:0.0/255.0 green:125/255.0 blue:0.0/255.0 alpha:1.0];
        [UINavigationBar appearance].standardAppearance = appearance;
        [UINavigationBar appearance].scrollEdgeAppearance = appearance;
    }

【讨论】:

  • 它对我有用,谢谢
【解决方案4】:

它在界面生成器中为我排序(xcode 13 - 已针对 iOS 13 及更高版本进行了测试)并且不需要检查 iOS 15 的可用性(即@available)

  1. 为导航栏选择标准和滚动边缘外观。

  1. 为两种外观选择相似的设置

祝你好运

【讨论】:

  • 这个答案非常有用。但是您能分享一下如何在界面生成器中更改标题颜色和标题字体。我尝试过,但没有成功。谢谢
  • 您需要根据自己的喜好设置titleTextAttributes 属性。
【解决方案5】:

就我而言,当我更新到 xcode13 和 iOS15 时。我发现 navigationBar 和 tabBar 变成透明的。我的 viewController 嵌入在 UINavigationController 中

经过一系列的测试,我发现设置navigationController的backgroundColor是最好的解决方法

navigationController?.view.backgroundColor = .yourColor

设置好颜色后,一切都很好

【讨论】:

  • 这对我来说是最好的答案
  • 这段代码放在哪里?
  • @MahmudurRahman 根据您的业务逻辑,您可以在任何地方获取您的 navigationController
【解决方案6】:

此代码可以放在任何地方,而不仅仅是在 App Delegate 中以修复 iOS15 上的问题:

if (@available(iOS 15, *)){
        UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
        [appearance configureWithOpaqueBackground];
        appearance.titleTextAttributes = @{NSForegroundColorAttributeName : UIColor.blackColor};
        appearance.backgroundColor = [UIColor colorWithRed:0.0/255.0 green:125/255.0 blue:0.0/255.0 alpha:1.0];
        self.navigationController.navigationBar.standardAppearance = appearance;
        self.navigationController.navigationBar.scrollEdgeAppearance = appearance;
    }

【讨论】:

【解决方案7】:

Xcode 13+

在 iOS 15 中,UIKit 将scrollEdgeAppearance(默认情况下会产生透明背景)的使用扩展到所有导航栏。背景是由滚动视图在导航栏后面滚动内容时控制的。

要恢复旧外观,您必须采用新的 UINavigationBar 外观 API,UINavigationBarAppearance。删除现有的自定义并执行以下操作:

    let appearance = UINavigationBarAppearance()
    appearance.backgroundColor = <your tint color>
    navigationBar.standardAppearance = appearance
    navigationBar.scrollEdgeAppearance = appearance

您也可以在上面的代码中使用外观代理,但将navigationBar.appearance().scrollEdgeAppearance = appearance 替换为最后一行。

【讨论】:

    【解决方案8】:

    我创建了此扩展程序以支持 iOS 15 和 iOS 12,以便仅在需要的位置更改导航栏背景(色调)和标题颜色,而不是在所有应用程序中。

    extension UINavigationBar {
      func update(backroundColor: UIColor? = nil, titleColor: UIColor? = nil) {
        if #available(iOS 15, *) {
          let appearance = UINavigationBarAppearance()
          appearance.configureWithOpaqueBackground()
          if let backroundColor = backroundColor {
            appearance.backgroundColor = backroundColor
          }
          if let titleColor = titleColor {
            appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor]
          }
          standardAppearance = appearance
          scrollEdgeAppearance = appearance
        } else {
          barStyle = .blackTranslucent
          if let backroundColor = backroundColor {
            barTintColor = backroundColor
          }
          if let titleColor = titleColor {
            titleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor]
          }
        }
      }
    }
    

    并像这样在需要的地方使用它(在我的例子中是 UIViewController 的 UI 配置)

      func configureNavigationController() {
        navigationController?.navigationBar.update(backroundColor: .blue, titleColor: .white)
      }
    

    【讨论】:

    • 它改变了状态栏的颜色!
    • 同样的问题
    【解决方案9】:

    目标 c 代码:在你的 viewDidLoad 函数中实现它


    if (@available(iOS 15, *)){
        UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
        [appearance configureWithOpaqueBackground];
        appearance.titleTextAttributes = @{NSForegroundColorAttributeName : UIColor.blackColor};
        appearance.backgroundColor = [UIColor colorWithRed:0.0/255.0 green:125/255.0 blue:0.0/255.0 alpha:1.0];
        self.navigationController.navigationBar.standardAppearance = appearance;
        self.navigationController.navigationBar.scrollEdgeAppearance = appearance;
    }
    

    【讨论】:

      【解决方案10】:

      任何寻找objective-c解决方案的人,请尝试以下代码:

      if (@available(iOS 15.0, *)) {
              UINavigationBarAppearance *navBarAppearance = [[UINavigationBarAppearance alloc] init];
              [navBarAppearance configureWithOpaqueBackground];
              navBarAppearance.backgroundColor = YOUR_COLOR;
              [navBarAppearance setTitleTextAttributes:
                      @{NSForegroundColorAttributeName:[UIColor whiteColor]}];
      
              self.navigationController.navigationBar.standardAppearance = navBarAppearance;
              self.navigationController.navigationBar.scrollEdgeAppearance = navBarAppearance;
          }
      

      【讨论】:

      • 这在this onethis one等其他答案中已经提到过。 在回答已有答案的旧问题时,请确保提供新颖的解决方案或比现有答案更好的解释。
      • @EricAya 嘿,我在分享答案之前确实尝试过查看,但是,我找不到 Objective-c 解决方案。
      • 我链接到的两个答案都在 Objective-C 中。也可能你没有注意到,但问题被标记为 Swift。
      【解决方案11】:

      对于 iOS 15 及更早版本,我将导航栏配置实现为不透明和半透明:

      extension UINavigationBar {
      static let defaultBackgroundColor = UIColor.red
      static let defaultTintColor = UIColor.white
      
      func setOpaque() {
          if #available(iOS 15, *) {
              let appearance = UINavigationBarAppearance()
              appearance.configureWithOpaqueBackground()
              appearance.backgroundColor = UINavigationBar.defaultBackgroundColor
              appearance.titleTextAttributes = [.foregroundColor: UINavigationBar.defaultTintColor]
              
              UINavigationBar.appearance().standardAppearance = appearance
              UINavigationBar.appearance().scrollEdgeAppearance = appearance
          } else {
              setBackgroundImage(UIImage(), for: UIBarPosition.any, barMetrics: UIBarMetrics.defaultPrompt)
              shadowImage = UIImage()
              barTintColor = UINavigationBar.defaultBackgroundColor
              titleTextAttributes = [.foregroundColor: UINavigationBar.defaultTintColor]
          }
          isTranslucent = false
          tintColor = UINavigationBar.defaultTintColor
      }
      
      func setTranslucent(tintColor: UIColor, titleColor: UIColor) {
          if #available(iOS 15, *) {
              let appearance = UINavigationBarAppearance()
              appearance.configureWithTransparentBackground()
              appearance.titleTextAttributes = [.foregroundColor: titleColor]
              standardAppearance = appearance
              scrollEdgeAppearance = appearance
          } else {
              titleTextAttributes = [.foregroundColor: titleColor]
              setBackgroundImage(UIImage(), for: UIBarMetrics.default)
              shadowImage = UIImage()
          }
          isTranslucent = true
          self.tintColor = tintColor
      }
      

      }

      【讨论】:

      • 这有帮助!谢谢
      【解决方案12】:

      如果我们需要更改背景颜色以及选中和未选中的项目颜色,只有这个代码在我的情况下有效

      我用它来改变物品的外观tabBarAppearance.stackedLayoutAppearance = tabBarItemAppearance

        if #available(iOS 15.0, *) {
              
              let tabBarAppearance = UITabBarAppearance()
              let tabBarItemAppearance = UITabBarItemAppearance()
              
              tabBarAppearance.backgroundColor = .white
              
              tabBarItemAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: Constants.Color.appDefaultBlue]
              tabBarItemAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
              
              tabBarAppearance.stackedLayoutAppearance = tabBarItemAppearance
              tabBar.standardAppearance = tabBarAppearance
              tabBar.scrollEdgeAppearance = tabBarAppearance
              
          }
      

      确保我们在 TabBar 类中使用此代码,以获得所需的结果,如果我们在 AppDelegate 中使用它来设置外观,它可能无法正常工作。

      【讨论】:

        【解决方案13】:

        在 AppDelegate.swift 中

        window?.backgroundColor = .white

        在我的情况下工作

        【讨论】:

          【解决方案14】:

          我尝试了各种方法,但下面的代码就像魔术一样用于恢复以前的版本。

              if #available(iOS 15, *) {
                  let appearance = UINavigationBarAppearance()
                  appearance.configureWithOpaqueBackground()
                  appearance.backgroundColor = .white
                  UINavigationBar.appearance().standardAppearance = appearance
                  UINavigationBar.appearance().scrollEdgeAppearance = appearance
              }
          

          【讨论】:

            【解决方案15】:

            此代码可以放在任何地方,而不仅仅是在 App Delegate 中以修复 iOS15 上的问题:

                            if #available(iOS 15, *) {
                            
                            let appearance = UINavigationBarAppearance()
                            appearance.configureWithOpaqueBackground()
                            appearance.backgroundColor = <desired UIColor>
                            navigationBar.standardAppearance = appearance;
                            navigationBar.scrollEdgeAppearance = navigationBar.standardAppearance
                            }
            

            【讨论】:

              【解决方案16】:

              像这样:

              let appearance = UINavigationBarAppearance()
              appearance.configureWithOpaqueBackground()
              appearance.backgroundColor = .red
              appearance.titleTextAttributes = [.font: 
              UIFont.boldSystemFont(ofSize: 20.0),
                                            .foregroundColor: UIColor.white]
              
              // Customizing our navigation bar
              navigationController?.navigationBar.tintColor = .white
              navigationController?.navigationBar.standardAppearance = appearance
              navigationController?.navigationBar.scrollEdgeAppearance = appearance
              

              我写了一篇关于它的新文章。

              https://medium.com/@eduardosanti/uinavigationbar-is-black-on-ios-15-44e7852ea6f7

              【讨论】:

                【解决方案17】:

                我编辑了@Charlie Seligman 共享的代码,因为它对我不起作用,因为我的一个屏幕中有一个滚动视图。 即使您有滚动视图和导航栏,以下代码也能正常工作。

                if #available(iOS 15, *) {
                            let appearance = UINavigationBarAppearance()
                            appearance.configureWithOpaqueBackground()
                            appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
                            appearance.backgroundColor = UIColor(red: 0.89, green: 0.06, blue: 0.00, alpha: 1.00)
                            UINavigationBar.appearance().standardAppearance = appearance
                            UINavigationBar.appearance().scrollEdgeAppearance = appearance
                        }
                

                【讨论】:

                  【解决方案18】:

                  仅使用情节提要执行此操作,以构建 @A​​tka 的答案,

                  您可以通过选择“自定义”标题属性来设置自定义标题文本属性

                  【讨论】:

                    猜你喜欢
                    • 2021-12-24
                    • 2021-12-02
                    • 2021-11-21
                    • 2020-09-19
                    • 2018-03-05
                    • 2016-12-20
                    • 2014-11-08
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多