Xcode 11.4。导航的标题颜色从情节提要中变为黑色


55

我最近将Xcode更新为11.4。当我在设备上运行该应用程序时,我注意到从情节提要中设置时,我所有导航项目的标题都变成了黑色。 在此处输入图片说明

您无法从代码中更改任何内容,下面的代码行不再起作用

self.navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]

我只使用一些iOS 13东西UINavigationBarAppearance使其工作

@available(iOS 13.0, *)
    private func setupNavigationBar() {
        let app = UINavigationBarAppearance()
        app.titleTextAttributes = [.foregroundColor: UIColor.white]
        app.backgroundColor = Constants.Color.barColor
        self.navigationController?.navigationBar.compactAppearance = app
        self.navigationController?.navigationBar.standardAppearance = app
        self.navigationController?.navigationBar.scrollEdgeAppearance = app

        self.navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]
    }

有人可以解释一下为什么吗?这是一个关键错误,还是一些新的隐藏功能?


3
同样的问题在这里,我无能为力。我认为这是一个错误:/
Jordan Favray

苹果。g 真?
Daniel


它是Xcode界面构建器Bug更新XCode到11.4.1
NinjaDeveloper

Answers:



36

这可以通过以下方式使用UINavigationBarAppearance为我修复:自定义应用程序的导航栏

if #available(iOS 13.0, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    appearance.backgroundColor = UIColor.black
    appearance.titleTextAttributes = [.foregroundColor: UIColor.white] // With a red background, make the title more readable.
    self.navigationBar.standardAppearance = appearance
    self.navigationBar.scrollEdgeAppearance = appearance
    self.navigationBar.compactAppearance = appearance // For iPhone small navigation bar in landscape.
} else {
    self.navigationBar.barTintColor = UIColor.black
    self.navigationBar.tintColor = UIColor.white
    self.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]
}

注意:我将UINavigationController子类化,并且这是从viewWillAppear的重写中调用的。

...或对于AppDelegate,应用范围内:

if #available(iOS 13.0, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    appearance.backgroundColor = UIColor.black
    appearance.titleTextAttributes = [
        NSAttributedStringKey.foregroundColor: UIColor.white
    ]

    let buttonAppearance = UIBarButtonItemAppearance()
    buttonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.white]
    appearance.buttonAppearance = buttonAppearance

    UINavigationBar.appearance().standardAppearance = appearance
    UINavigationBar.appearance().scrollEdgeAppearance = appearance
    UINavigationBar.appearance().compactAppearance = appearance

    UIBarButtonItem.appearance().tintColor = UIColor.white
} else {
    UINavigationBar.appearance().barTintColor = UIColor.black
    UINavigationBar.appearance().titleTextAttributes = [
        NSAttributedStringKey.foregroundColor: UIColor.white
    ]
    UINavigationBar.appearance().tintColor = UIColor.white

    UIBarButtonItem.appearance().tintColor = UIColor.white
}

...对于AppDelegate,应用范围内,在Objective-C中:

if (@available(iOS 13, *)) {
    UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
    [appearance configureWithOpaqueBackground];
    appearance.backgroundColor = UIColor.whiteColor;
    appearance.titleTextAttributes = titleAttributes;

    UIBarButtonItemAppearance *buttonAppearance = [[UIBarButtonItemAppearance alloc] init];
    buttonAppearance.normal.titleTextAttributes = barButtonItemAttributes;
    appearance.buttonAppearance = buttonAppearance;

    UINavigationBar.appearance.standardAppearance = appearance;
    UINavigationBar.appearance.scrollEdgeAppearance = appearance;
    UINavigationBar.appearance.compactAppearance = appearance;

    [[UINavigationBar appearance] setTintColor:UIColor.blackColor];
} else {
    [[UINavigationBar appearance] setBarTintColor:UIColor.whiteColor];
    [[UINavigationBar appearance] setTintColor:UIColor.blackColor];
    [[UINavigationBar appearance] setTranslucent:false];
    [[UINavigationBar appearance] setTitleTextAttributes: titleAttributes];
    [[UIBarButtonItem appearance] setTitleTextAttributes:barButtonItemAttributes forState:UIControlStateNormal];
}

谢谢,这是正确的答案!,在iOS 13上,Apple添加UINavigationBarAppearance()了Apple,并且没有理由不依赖于旧的Xcode,但是由于Xcode 11.4必须使用它,UINavigationBarAppearance()否则Title颜色将始终为Black。
罗勒

appearance.largeTitleTextAttributes大标题。
Skoua

效果很好,谢谢您!
slicerdicer

@slicerdicer-是的!有关示例,请参见我更新的答案。干杯。
Stu Carney

1
@Richard-我刚刚添加了Objective-C的答案。抱歉,直到今天我才看到您的评论。
Stu Carney

14

在情节提要上,对于导航控制器,将“ Bar Tint”更改为“ Default”值,然后在代码上可以像往常一样更改它。


3
最佳答案。真。
弗拉基米尔·普里加林

2
这是正确的方法
雨果

1
最佳anwer❗️时期。
shadowsheep

2
@ JCutting8是的,没错。但是,如果您未在情节提要中设置默认颜色,则使用Xcode 11.4,以编程方式更改它不会起作用。我不知道这是否是一个问题。
shadowsheep

1
这是魔术!
ekashking

6

不确定是否是错误。

我们解决问题的方法是在项目设置中将“状态栏样式”设置为暗或亮。这将强制以某种方式显示状态栏文本的颜色,而不是根据处于亮或暗模式下的设备来确定颜色。

此外,您需要在Info.plist中将“基于View Controller的状态栏外观”值设置为“ NO”。没有该值,“状态栏样式”将被覆盖。

接下来,创建一个自定义导航控制器,并在情节提要中实现它。

class CustomNavigationController: UINavigationController {

 override func viewDidLoad() {
    super.viewDidLoad()
    setNavBar()
 }

 func setNavBar() {
    if #available(iOS 13.0, *) {
        let appearance = UINavigationBarAppearance()
        appearance.configureWithOpaqueBackground()
        appearance.backgroundColor = UIColor.blue
        appearance.titleTextAttributes = [.foregroundColor: UIColor.yellow]
        self.navigationBar.standardAppearance = appearance
        self.navigationBar.scrollEdgeAppearance = appearance
        self.navigationBar.compactAppearance = appearance
    } else {
        self.navigationBar.barTintColor = UIColor.blue
        self.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.yellow]
    }
  }
}

*设置了颜色,以便您可以清楚地看到它们的工作状态。

我发现最好在ViewDidLoad中设置代码,而不是在ViewDidAppear中设置代码,因为只有在向后导航并重新加载后,才在初始加载时未设置颜色。

我还发现此问题可能与NavBar的“ Bar Tint”有关。当我们第一次尝试解决它时,我们将“ Bar Tint”设置为默认值,这似乎也解决了该错误。但是,它做到了,因此我们无法获得所需的NavBar背景色。因此,在我的情节提要中,我确保将此值设置为default只是为了很好。

希望能帮助到你


这确实有效。似乎只是在设置无效的全局样式。
蒙哥

定义了苹果方面的错误。忍不住要打破>。<
Michael McKenna


0

与Stu Carney在3/25上的回应类似,我添加了更多实现细节。

创建UINavigationController的子类。将以下内容添加到viewWillAppear中:

let isDarkMode = UserDefaults.standard.bool(forKey: "DarkMode")
let titleColor: UIColor = isDarkMode ? .white : .black
let navBarColor: UIColor = isDarkMode ? .black : .white
let tintColor: UIColor = isDarkMode ? .yellow : .red  //back button text and arrow color, as well as right bar button item

if #available(iOS 13.0, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    appearance.backgroundColor = navBarColor
    appearance.titleTextAttributes = [.foregroundColor: titleColor]
    appearance.largeTitleTextAttributes = [.foregroundColor: titleColor]

    self.navigationBar.standardAppearance = appearance
    self.navigationBar.scrollEdgeAppearance = appearance
    self.navigationBar.compactAppearance = appearance // For iPhone small navigation bar in landscape.

    self.navigationBar.tintColor = tintColor //changes back button text and arrow color, as well as right bar button item
} else {
    self.navigationBar.barTintColor = navBarColor
    self.navigationBar.tintColor = tintColor
    self.navigationBar.titleTextAttributes = [.foregroundColor: titleColor]
    self.navigationBar.largeTitleTextAttributes = [.foregroundColor: titleColor]
}

然后覆盖preferredStatusBarStyle

override var preferredStatusBarStyle: UIStatusBarStyle {
    let isDarkMode = UserDefaults.standard.bool(forKey: "DarkMode")
    return isDarkMode ? .lightContent : .default
}

如果要动态更新导航栏和状态栏(例如,通过UISwitch IBAction或选择器方法),请添加以下内容:

navigationController?.loadView()
navigationController?.topViewController?.setNeedsStatusBarAppearanceUpdate()

另外,请确保将所有导航栏和导航栏按钮设置为IB中的默认颜色。Xcode似乎存在一个错误,其中IB颜色覆盖了以编程方式设置的颜色。


0

就我而言,在将Xcode从11.3升级到11.4之后,就会发生此错误。因此,为了将图像设置为导航栏中的背景,我必须更改代码以使其无效。

if #available(iOS 13.0, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    let backgroundImage = UIImage(named: "{NAVBAR_IMAGE_NAME}")?.resizableImage(withCapInsets: UIEdgeInsets.zero, resizingMode: .stretch)
    appearance.backgroundImage = backgroundImage
    self.navigationController?.navigationBar.compactAppearance = appearance
    self.navigationController?.navigationBar.standardAppearance = appearance
    self.navigationController?.navigationBar.scrollEdgeAppearance = appearance        
} else {
    self.navigationController?.navigationBar.barTintColor = Utils.themeColor
    let backgroundImage = UIImage(named: "{NAVBAR_IMAGE_NAME}")?.resizableImage(withCapInsets: UIEdgeInsets.zero, resizingMode: .stretch)
    self.navigationController?.navigationBar.setBackgroundImage(backgroundImage, for: .default)
    self.navigationController?.navigationBar.shadowImage = UIImage()
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.