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

Posted

技术标签:

【中文标题】Xcode 11.4。导航的标题颜色从情节提要中变为黑色【英文标题】:Xcode 11.4. Navigation's Title Color gone BLACK from storyboard 【发布时间】:2020-07-05 23:53:36 【问题描述】:

我最近将我的 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]
    

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

【问题讨论】:

这里有同样的问题,我找不到解决这个问题的方法。我认为这是一个错误:/ 苹果。哎呀。真的吗? 试试这个***.com/a/61003557/3887987 它是 Xcode Interface builder Bug Update XCode to 11.4.1 【参考方案1】:

这为我解决了这个问题,改用 UINavigationBarAppearance,来自:Customizing Your App’s Navigation Bar

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(),并且在旧的 Xcode 上我们无缘无故地依赖它,但由于 Xcode 11.4 它必须使用UINavigationBarAppearance(),否则标题颜色将始终为黑色。 appearance.largeTitleTextAttributes 用于大标题。 这很好用,谢谢!,有没有办法从 AppDelegate 普遍做到这一点? @slicerdicer - 是的!例如,请参阅我更新的答案。干杯。 @Richard - 我刚刚添加了 Objective-C 的答案。抱歉,直到今天我才看到你的评论。【参考方案2】:

在情节提要上,为您的导航控制器将“条形色调”更改为其“默认”值,然后在您的代码上像往常一样更改它。

【讨论】:

最佳答案。真的。 这才是正道 最佳答案❗️期。 @JCutting8 是的,没错。但是对于 Xcode 11.4,如果您没有在情节提要中设置默认颜色,则以编程方式更改它不起作用。我不知道这是否是一个问题。 这是一个魔术!【参考方案3】:

Apple 终于在 11.4.1 版本中修复了它

https://developer.apple.com/documentation/xcode_release_notes/xcode_11_4_1_release_notes

【讨论】:

【参考方案4】:

不确定是否是错误。

我们修复它的方法是在项目设置中将“状态栏样式”设置为深色或浅色内容。这将强制状态栏文本颜色以某种方式而不是根据设备处于浅色或深色模式来确定。

此外,您需要在 Info.plist 中将值“基于控制器的状态栏外观”设置为“否”。如果没有该值,“状态栏样式”将被覆盖。

接下来创建一个自定义导航控制器并在您的故事板中实现它。

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 背景颜色。因此,在我的故事板中,我确保将此值设置为默认值只是为了更好地衡量。

希望对你有帮助

【讨论】:

这确实有效。似乎只是设置了不起作用的全局样式。 定义苹果端的一个错误。忍不住打破东西>. 【参考方案5】:

不需要解决方法。这是 Xcode Interface Builder 中的一个错误。 Apple 发布 Xcode 11.4.1 更新

来自 Apple 开发者发布说明

界面生成器

修复了导致某些 UINavigationBar 外观属性的问题 在情节提要和 XIB 文档中设置以在构建时被忽略 Xcode 11.4。 (60883063) (FB7639654)

https://developer.apple.com/documentation/xcode_release_notes/xcode_11_4_1_release_notes

【讨论】:

【参考方案6】:

与 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 颜色会覆盖以编程方式设置的颜色。

【讨论】:

【参考方案7】:

就我而言,在我将 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()

【讨论】:

以上是关于Xcode 11.4。导航的标题颜色从情节提要中变为黑色的主要内容,如果未能解决你的问题,请参考以下文章

xcode:颜色图标在情节提要中显示为灰色方块

Xcode 6,主情节提要,颜色关闭

如何在情节提要 Xcode 11 中的视图之间将边距设置为零

Xcode 快速导航栏在模拟器运行时消失,但在情节提要中不会

Xcode 11.4 导航栏按钮问题

导航控制器有时会使用情节提要推送到黑屏