82

问题演示

重现问题的前提条件:

  1. Xcode 11 beta + iOS 13(2019 年 6 月 12 日之前的最新版本)
  2. 导航栏处于大文本模式
  3. 指定导航栏的颜色。

在真实设备中,状态栏将保持为白色,位于绿色导航栏上方。

我尝试过的解决方案:

  1. 恢复到 iOS12 就可以解决,但最终还是会遇到 iOS13...
  2. 禁用大文本模式将解决它...
  3. 隐藏状态栏将修复它,但它会导致状态文本与导航栏项目重叠。

有任何想法吗?感谢任何帮助。

4

17 回答 17

218

这里不需要任何技巧或时髦。关键是定义所需的外观并在导航栏standardAppearance及其scrollEdgeAppearance. 我在整个应用程序的基本导航控制器子类的 init 中有以下内容:

if #available(iOS 13.0, *) {
    let navBarAppearance = UINavigationBarAppearance()
    navBarAppearance.configureWithOpaqueBackground()
    navBarAppearance.titleTextAttributes = [.foregroundColor: UIColor.white]
    navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
    navBarAppearance.backgroundColor = <insert your color here>
    navigationBar.standardAppearance = navBarAppearance
    navigationBar.scrollEdgeAppearance = navBarAppearance
}

在此处输入图像描述

于 2019-07-22T19:38:30.717 回答
17

如果问题是您想在显示大标题时为导航栏提供颜色,请使用新的 UINavigationBarAppearance 类。

let app = UINavigationBarAppearance()
app.backgroundColor = .blue
self.navigationController?.navigationBar.scrollEdgeAppearance = app
于 2019-07-08T20:05:46.773 回答
16

在 iOS 13 上,根据 Apple 人机界面指南,使用大标题的导航栏具有透明颜色。在此处查看更多信息:

在 iOS 13 及更高版本中,大标题导航栏默认不包含背景材质或阴影。此外,随着人们开始滚动内容,大标题会转换为标准标题

于 2019-07-07T19:28:25.763 回答
14

通用代码

let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithOpaqueBackground()
navBarAppearance.backgroundColor = // your color
navBarAppearance.shadowImage = nil // line
navBarAppearance.shadowColor = nil // line
UINavigationBar.appearance(whenContainedInInstancesOf: [UINavigationController.self]).standardAppearance = navBarAppearance
UINavigationBar.appearance(whenContainedInInstancesOf: [UINavigationController.self]).scrollEdgeAppearance = navBarAppearance
于 2019-09-03T18:51:14.777 回答
12

我的导航栏扩展,iOS 13 Swift 5

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

如何使用:

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

如果你想要轻量的内容,在 info.plist 中将基于 ViewController 的状态栏......设置为 NO

如果您不希望 largeTitles 将其设置为 false

在 iOS 13 上测试,希望对您有所帮助:)

于 2019-10-13T07:03:25.680 回答
11

Objective C 解决方案和 iOS 13

UINavigationBarAppearance* navBarAppearance = [self.navigationController.navigationBar standardAppearance];
        [navBarAppearance configureWithOpaqueBackground];
        navBarAppearance.titleTextAttributes = @{NSForegroundColorAttributeName:TitleColor};
        navBarAppearance.largeTitleTextAttributes = @{NSForegroundColorAttributeName: TitleColor};
        navBarAppearance.backgroundColor = TopColor;
        self.navigationController.navigationBar.standardAppearance = navBarAppearance;
        self.navigationController.navigationBar.scrollEdgeAppearance = navBarAppearance;
于 2019-10-02T20:19:07.370 回答
5

如果要删除导航栏下方的下划线

if #available(iOS 13.0, *) {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.titleTextAttributes = [.foregroundColor: UIColor.white]
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
        navBarAppearance.backgroundColor = <yourColor>
        navBarAppearance.backgroundImage = UIImage()
        navBarAppearance.shadowImage = UIImage()
        navBarAppearance.shadowColor = .clear
        self.navigationController?.navigationBar.standardAppearance = navBarAppearance
        self.navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
   
    }
于 2020-07-07T16:53:21.843 回答
4

对于 iOS 13,我遇到了条形阴影线出现的问题。设置 Bars 阴影图像可以nil解决该问题。

func configureNavigation() {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.myColor,
                                                     .font: UIFont(name: "MyFont", size: 42)!]
        navBarAppearance.backgroundColor = .white
        navigationController?.navigationBar.isTranslucent = false
        navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
    }

带阴影的图像

func configureNavigation() {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.myColor,
                                                     .font: UIFont(name: "MyFont", size: 42)!]
        navBarAppearance.backgroundColor = .white
        navBarAppearance.shadowColor = nil
        navigationController?.navigationBar.isTranslucent = false
        navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
    }

没有阴影的图像

于 2019-09-07T14:17:28.397 回答
3

完全可行的代码:

 let navigationBarAppearace = UINavigationBar.appearance()
    navigationBarAppearace.tintColor = .tintColor
    navigationBarAppearace.barTintColor = .barTintColor
    navigationBarAppearace.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.tintColor]

if #available(iOS 13.0, *) {
  let navBarAppearance = UINavigationBarAppearance()
  navBarAppearance.configureWithOpaqueBackground()
  navBarAppearance.titleTextAttributes = [.foregroundColor: UIColor.tintColor]
  navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.tintColor]
  navBarAppearance.backgroundColor = <insert your color here>
  navigationBarAppearace.standardAppearance = navBarAppearance // have a look here ;)
  navigationBar.scrollEdgeAppearance = navBarAppearance
}

祝大家好运,和平!

于 2020-09-25T20:44:11.080 回答
1

感谢迈克和汉斯的回答。我的案例是半透明状态栏和 alpha 0.5 的导航栏。iOS13 看起来很复杂。以下是我的测试结果,如果您希望两者都透明,则可以使用。

if #available(iOS 13.0, *) {
                let navBarAppearance = UINavigationBarAppearance()
                // This only set top status bar as transparent, not the nav bar.
                navBarAppearance .configureWithTransparentBackground()
                // This set the color for both status bar and nav bar(alpha 1).
                navBarAppearance.backgroundColor = UIColor.red.withAlphaComponent(0.5)
                navigationController?.navigationBar.standardAppearance = navBarAppearance
                navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
                // Nav bar need sets to translucent for both nav bar and status bar to be translucent.
                navigationController?.navigationBar.isTranslucent = true
                // // Need to reset nav bar's color to make it clear to display navBarAppearance's color
                navigationController?.navigationBar.backgroundColor = UIColor.clear
               } 
于 2019-07-26T18:53:45.847 回答
1

在将我的一个应用程序更新为更兼容 iOS 13 时,我遇到了类似的问题。正如Hans上面提到的,大标题默认是透明的。如果您像我一样是 Storyboard 的重度用户,那么侧栏中还有另一个设置很容易打开。

如果您单击故事板中的导航栏,它通常默认选择Navigation Item,并且您不会获得任何自定义选项。选择Navigation Bar它上面的选项,然后您可以在右侧的检查器中选择您想要的任何自定义背景颜色。

在此处输入图像描述

于 2019-10-23T13:22:54.867 回答
0

斯威夫特 5

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)

    let userInterfaceStyle = traitCollection.userInterfaceStyle
    modeDetect(userInterfaceStyle: userInterfaceStyle)

}

override func viewDidAppear(_ animated: Bool) {
    navigationController?.navigationBar.barStyle = .black
    navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]
}

func modeDetect(userInterfaceStyle: UIUserInterfaceStyle) {
    switch userInterfaceStyle {
    case .light:
        navigationController?.navigationBar.barTintColor = .systemPink
    case .dark:
        navigationController?.navigationBar.barTintColor = .systemBackground
    default:
        break
    }
}
于 2019-09-17T22:25:34.967 回答
0

我发现使用故事板你必须伪造导航栏(假设你的绿色是不透明的,只适用于不透明的导航栏)。我发现最好的方法是创建一个适合安全区域插图的占位符视图(紫色),然后在导航栏(青色/蓝色)后面添加一个假视图,即剩余高度。适用于我的项目,但是是的,这有点麻烦。Xcode 11 beta 4 的屏幕截图显示了状态栏破解所需的约束

编辑:这主要用于 LaunchScreen.storyboard,您不能在其中使用自定义视图控制器类。

于 2019-07-22T15:22:54.017 回答
0

使用适当的参数调用此函数。此代码工作正常。

open func showNavigationBar(large: Bool,
                            animated: Bool,
                            isTransparabar: Bool,
                            titleColor: UIColor,
                            barBackGroundColor: UIColor,
                            fontSize: CGFloat) {

        navigationController?.navigationBar.barTintColor = barBackGroundColor
        navigationController?.navigationBar.backgroundColor = barBackGroundColor
        navigationController?.navigationBar.isTranslucent = true
        self.navigationController?.setNavigationBarHidden(false, animated: animated)
        if large {
            self.navigationController?.navigationBar.prefersLargeTitles = true
            if #available(iOS 13.0, *) {
                let appearance = UINavigationBarAppearance()
                appearance.backgroundColor = barBackGroundColor
                appearance.titleTextAttributes = [.foregroundColor: titleColor]
                appearance.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor]

                navigationController?.navigationBar.standardAppearance = appearance
                navigationController?.navigationBar.compactAppearance = appearance
                navigationController?.navigationBar.scrollEdgeAppearance = appearance
            } else {
                self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor]
            }
        } else {
            self.navigationController?.navigationBar.prefersLargeTitles = false
            self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor!]
        }
    }
于 2019-10-24T11:17:04.753 回答
0

以下 Objective-C 代码使 iOS 13 导航栏的行为与我之前的版本相似:

    if (@available(iOS 13.0, *)) {
        // Setup iOS 13 navigation bar
        sharedSelector.navigationBar.scrollEdgeAppearance = sharedSelector.navigationBar.standardAppearance;
    } else {
        // Fallback on earlier versions
    }
于 2019-09-27T19:49:04.073 回答
0

我只是在故事板中打开半透明

像这儿

于 2021-09-30T17:47:41.570 回答
-1

迈克的解决方案很棒。

我提供了一种替代方法来更改适用于任何 iOS 版本的 UINavigationBar 颜色。

我们基本上将利用我们可以将 Image 设置为 UINavigationBar 的背景这一事实。

第一的

添加扩展以从任何 UColor 生成 UIImage。请注意,如果需要,您还可以稍后编写扩展以从十六进制或其他格式生成 UIColor。

extension UIColor {
    func image(_ size: CGSize = CGSize(width: 1, height: 1)) -> UIImage {
        return UIGraphicsImageRenderer(size: size).image { rendererContext in
            self.setFill()
            rendererContext.fill(CGRect(origin: .zero, size: size))
        }
    }

}

感谢@neoneye的这个伟大的UIColor扩展:)

第二

现在我们开始谈正事:

private func setupNavigationBarAppearance(navBar: UINavigationBar) {
    navBar.isTranslucent = false
    let navBarColorImage = UIColor.blue.image()
    navBar.setBackgroundImage(navBarColorImage, for: .default)
    navBar.tintColor = UIColor.white
}

因为我们已经将不透明的彩色图像设置为背景,所以我们不需要检查 iOS 13

我希望这可以帮助一些人自定义他们的导航栏。

干杯!

于 2019-10-24T22:18:25.017 回答