Xcode 11.4. Navigation's Title Color gone BLACK from storyboard

前端 未结 7 959
挽巷
挽巷 2020-12-08 06:05

I recently updated my Xcode to 11.4. When I run the app on the device, i\'ve noticed that all my navigations item\'s titles gone fully black when being set from storyboard.

相关标签:
7条回答
  • 2020-12-08 06:37

    Apple finally fixed it in version 11.4.1

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

    0 讨论(0)
  • 2020-12-08 06:40

    Not sure if it's a bug or not.

    The way we fixed it is by setting the "Status Bar Style" to either dark or light content in project setting. This will force the Status Bar text color a certain way rather than being determined based on the devices being in Light or Dark mode.

    In addition, you need to set the value "View controller-based status bar appearance" to "NO" in your Info.plist. without that value the "Status Bar style" will be overridden.

    Next create a custom navigation controller and implement it in your storyboards.

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

    *Colors are set so you can see them clearly working.

    I found it was better to set the code in ViewDidLoad rather than ViewDidAppear because my colors were not being set on the initial load, only after navigating back and reloading.

    I also found that this issue might be tied to the "Bar Tint" of a NavBar. when we were first trying to resolve it, we set the "Bar Tint" to default and that seemed resolve the error too. However, it made it so we couldn't get the NavBar background color what we wanted. So in my storyboards I made sure to set this value to default just for good measure.

    Hope it helps

    0 讨论(0)
  • 2020-12-08 06:43

    In my case, after I upgraded Xcode from 11.3 to 11.4 this bug occurred. So I have to change my code to blow in order to set an image as background in the navigation bar.

    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()
    }
    
    0 讨论(0)
  • 2020-12-08 06:44

    no need for the workaround.it is a bug in Xcode Interface Builder. Apple release Update for Xcode 11.4.1

    from Apple developer release notes

    Interface Builder

    Fixed an issue that caused some UINavigationBar appearance properties set in storyboard and XIB documents to be ignored when building with Xcode 11.4. (60883063) (FB7639654)

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

    0 讨论(0)
  • 2020-12-08 06:46

    This fixed it for me, using UINavigationBarAppearance instead, from: 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]
    }
    

    Note: I subclassed UINavigationController, and this was called from the override of viewWillAppear.

    ...or for AppDelegate, app-wide:

    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
    }
    

    ...for AppDelegate, app-wide, in 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];
    }
    
    0 讨论(0)
  • 2020-12-08 06:57

    Similar to Stu Carney's response on 3/25, I added a few more implementation details.

    Create a subclass of UINavigationController. Add the following to 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]
    }
    

    Then override preferredStatusBarStyle:

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

    If you want to update the navigation bar and status bar dynamically, like from a UISwitch IBAction or selector method, add the following:

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

    Also, be sure to set all your navigation bars and bar buttons to the default colors in IB. Xcode seems to have a bug where the the IB colors override the colors set programatically.

    0 讨论(0)
提交回复
热议问题