IOS15导航条透明

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

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

https://developer.apple.com/forums/thread/682420的苹果开发者论坛上,它声明 在 iOS15中,UIKit 将 scrollEdge卖相(默认情况下会产生一个透明的背景)的使用扩展到了所有的导航条要恢复旧的外观,必须采用新的 UINavigationBar 外观 API

我添加了以下代码(来自上面的链接)到应用程序代理“ application (_ application: UIApplication,did FinishLaunchingWithOptions 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 实现错误?

72302 次浏览

没有必要在故事板中更改任何内容。 下面是添加到应用程序代理 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
}

注意,如果没有指定 title text 属性,那么有必要将 title text 属性设置为“ white”,因为 title text 默认为 black。

还要注意的是,这应该只适用于 iOS 15.0或更高版本。它不适用于早期版本,因为故事板导航栏自定义色彩是默认行为。

要使用自己的配色方案,请使用以下颜色:

斯威夫特

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

要获得默认的半透明行为,就像 iOS15之前默认的那样,只需设置 scrollEdgeAppearance:

斯威夫特

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

目标 C

if (@available(iOS 15.0, *)) {
[UINavigationBar appearance].scrollEdgeAppearance = [[UINavigationBarAppearance alloc] init];
}

如果有人需要 目标 C版本的 G ・史蒂夫的答案

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

这段代码可以放在任何地方,而不仅仅是应用程序代理来修复 iOS15上的问题:

                if #available(iOS 15, *) {
                

let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = <desired UIColor>
navigationBar.standardAppearance = appearance;
navigationBar.scrollEdgeAppearance = navigationBar.standardAppearance
}

这样做:

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

我创建这个扩展是为了支持 iOS15和 iOS12,以便只在需要的地方改变导航栏背景(色调)和标题颜色,而不是在所有应用程序中。

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

在我的例子中,当我更新到 xcode13和 iOS15时。我发现导航栏和标签栏变得透明。我的 viewController 嵌入在 UINavigationController 中

enter image description here

经过一系列的测试,我发现设置导航控制器的背景颜色是解决这个问题的最好方法

navigationController?.view.backgroundColor = .yourColor

一旦设置好颜色,一切都没问题

enter image description here

我的导航栏配置实现为不透明和半透明的 IOS15和旧版本:

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
}

}

它为我按 Interface Builder 排序(xcode 13经过 iOS 13及以上版本的测试) ,而不需要检查 iOS 15的可用性(例如@may)

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

enter image description here

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

enter image description here

enter image description here

祝你好运

我已经编辑了@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
}

Objective c code: 在 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;
}

这段代码可以放在任何地方,而不仅仅是应用程序代理来修复 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;
}

如果我们需要改变背景颜色和选择和未选择的项目颜色,只有这个代码工作的情况下我

我已经用这个来改变项目外观 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.swift

window?.backgroundColor = .white

在我的案子里起作用了

任何寻找目标 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;
}

Xcode 13 +

在 iOS15中,UIKit 将 scrollEdgeAppearance的使用范围扩展到了所有的导航条,scrollEdgeAppearance默认会产生一个透明的背景。背景由滚动视图在导航栏后滚动内容时控制。

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

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

您还可以将外观代理与上面的代码一起使用,但是可以用 navigationBar.appearance().scrollEdgeAppearance = appearance代替最后一行。

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

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

为了做到这一点与故事板只,建立在@Atka 的答案,

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

Scroll edge title attributes

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

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
}