126

我的 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?

4

19 回答 19

112

要使用您自己的配色方案,请使用以下内容:

迅速

// 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;
}

要获得默认的半透明行为,默认的方式是在 iOS 15 之前,只需设置scrollEdgeAppearance

迅速

if #available(iOS 15, *) {
    UINavigationBar.appearance().scrollEdgeAppearance = UINavigationBarAppearance()
}

Objective-C

if (@available(iOS 15.0, *)) {
    [UINavigationBar appearance].scrollEdgeAppearance = [[UINavigationBarAppearance alloc] init]; 
}
于 2021-09-10T17:11:07.613 回答
73

无需更改情节提要中的任何内容。这是添加到 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 或更高版本。它不适用于早期版本,因为故事板导航栏自定义色调是默认行为。

于 2021-09-09T19:50:54.770 回答
41

如果有人需要G. Steve 的答案的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;
    }
于 2021-09-16T13:44:25.130 回答
25

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

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

在此处输入图像描述

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

在此处输入图像描述

在此处输入图像描述

祝你好运

于 2021-10-03T18:34:11.530 回答
13

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

在此处输入图像描述

经过一系列的测试,我发现 NavigationController 的设置背景颜色是解决这个问题的最佳方法

navigationController?.view.backgroundColor = .yourColor

一旦设置了颜色,一切都很好

在此处输入图像描述

于 2021-09-24T02:11:02.467 回答
7

此代码可以放在任何地方,而不仅仅是在 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;
    }
于 2021-10-08T09:43:55.720 回答
6

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最后一行。

于 2021-10-28T09:16:32.280 回答
4

我创建了这个扩展来支持 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)
  }
于 2021-09-22T13:55:32.097 回答
2

任何寻找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;
    }
于 2021-10-27T13:55:25.543 回答
2

对于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
}

}

于 2021-09-27T16:51:27.900 回答
2

目标 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;
}
于 2021-10-06T16:46:07.060 回答
1

在 AppDelegate.swift 中

窗口?.backgroundColor = .white

在我的情况下工作

于 2021-10-26T08:03:42.997 回答
1

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

    if #available(iOS 15, *) {
        let appearance = UINavigationBarAppearance()
        appearance.configureWithOpaqueBackground()
        appearance.backgroundColor = .white
        UINavigationBar.appearance().standardAppearance = appearance
        UINavigationBar.appearance().scrollEdgeAppearance = appearance
    }
于 2021-11-10T13:26:20.823 回答
1

如果您想设置没有标题和透明导航栏的自定义后退按钮,这是一个版本

let backImg: UIImage = #imageLiteral(resourceName: "back")

if #available(iOS 15, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    appearance.titleTextAttributes = [.foregroundColor: UIColor.black]
    appearance.setBackIndicatorImage(backImg, transitionMaskImage: backImg)
    appearance.backButtonAppearance.normal.titlePositionAdjustment =
    UIOffset(horizontal: -1000.0, vertical: 0)
    UINavigationBar.appearance().standardAppearance = appearance
    UINavigationBar.appearance().scrollEdgeAppearance = appearance
}
于 2022-01-04T15:10:03.600 回答
1

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

我用它来改变项目的外观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 中使用它来设置外观,它可能无法正常工作。

于 2021-10-14T06:38:22.647 回答
0

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

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

滚动边缘标题属性

于 2021-12-02T15:57:38.550 回答
0

像这样制作:

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

于 2021-09-22T13:24:25.203 回答
0

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

                if #available(iOS 15, *) {
                
                let appearance = UINavigationBarAppearance()
                appearance.configureWithOpaqueBackground()
                appearance.backgroundColor = <desired UIColor>
                navigationBar.standardAppearance = appearance;
                navigationBar.scrollEdgeAppearance = navigationBar.standardAppearance
                }
于 2021-09-20T20:59:13.023 回答
0

我已经编辑了@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
        }
于 2021-10-05T06:15:45.330 回答