Can't change UINavigationBar prompt color

I was able to make the prompt color white on iOS 11 was setting the barStyle to black. I set the other color attributes (like the desired background color) using the appearance proxy:

myNavbar.barStyle = UIBarStyleBlack; // Objective-C
myNavbar.barStyle = .black // Swift

It seems like you're right about this one. You need to use UIAppearance to style the prompt text on iOS 11.

I've filed radar #34758558 that the titleTextAttributes property just stopped working for prompt in iOS 11.

The good news is that there are a couple of workarounds, which we can uncover by using Xcode's view hierarchy debugger:

Screenshot of UINavigation Bar Prompt on iOS 11

// 1. This works, but potentially changes *all* labels in the navigation bar. 
// If you want this, it works.
UILabel.appearance(whenContainedInInstancesOf: [UINavigationBar.self]).textColor = UIColor.white

The prompt is just a UILabel. If we use UIAppearance's whenContainedInInstancesOf:, we can pretty easily update the color the way we want.

If you look closely, you'll notice that there's also a wrapper view on the UILabel. It has its own class that might respond to UIAppearance...

Screenshot of private UINavigationBar subview

// 2. This is a more precise workaround but it requires using a private class.

if let promptClass = NSClassFromString("_UINavigationBarModernPromptView") as? UIAppearanceContainer.Type
{
  UILabel.appearance(whenContainedInInstancesOf: [promptClass]).textColor = UIColor.white
}

I'd advise sticking to the more general solution, since it doesn't use private API. (App review, etc.) Check out what you get with either of these two solutions:

Properly colored prompt text


You may use

for view in self.navigationController?.navigationBar.subviews ?? [] {
    let subviews = view.subviews
    if subviews.count > 0, let label = subviews[0] as? UILabel {
        label.textColor = UIColor.white
        label.backgroundColor = UIColor.red
    }
}

It will be a temporary workaround until they'll fix it