I am unable to change the prompt color on my navigation bar. I\'ve tried the code below in viewDidLoad, but nothing happens.
self.navigationCont
I've found next work around for iOS 11.
You need set at viewDidLoad
navigationItem.prompt = UINavigationController.fakeUniqueText
and after that put next thing
navigationController?.promptLabel(completion: { label in
label?.textColor = .white
label?.font = Font.regularFont(size: .p12)
})
extension UINavigationController {
public static let fakeUniqueText = "\n\n\n\n\n"
func promptLabel(completion: @escaping (UILabel?) -> Void) {
gloabalThread(after: 0.5) { [weak self] in
guard let `self` = self else {
return
}
let label = self.findPromptLabel(at: self.navigationBar)
mainThread {
completion(label)
}
}
}
func findPromptLabel(at view: UIView) -> UILabel? {
if let label = view as? UILabel {
if label.text == UINavigationController.fakeUniqueText {
return label
}
}
var label: UILabel?
view.subviews.forEach { subview in
if let promptLabel = findPromptLabel(at: subview) {
label = promptLabel
}
}
return label
}
}
public func mainThread(_ completion: @escaping SimpleCompletion) {
DispatchQueue.main.async(execute: completion)
}
public func gloabalThread(after: Double, completion: @escaping SimpleCompletion) {
DispatchQueue.global().asyncAfter(deadline: .now() + after) {
completion()
}
}
I suggest using a custom UINavigationBar subclass and overriding layoutSubviews:
- (void)layoutSubviews {
[super layoutSubviews];
if (self.topItem.prompt) {
UILabel *promptLabel = [[self recursiveSubviewsOfKind:UILabel.class] selectFirstObjectUsingBlock:^BOOL(UILabel *label) {
return [label.text isEqualToString:self.topItem.prompt];
}];
promptLabel.textColor = self.tintColor;
}
}
Basically I'm enumerating all UILabels in the subview hierarchy and check if their text matches the prompt text. Then we set the textColor to the tintColor (feel free to use a custom color). That way, we don't have to hardcode the private _UINavigationBarModernPromptView class as the prompt label's superview. So the code is be a bit more future-proof.
Converting the code to Swift and implementing the helper methods recursiveSubviewsOfKind: and selectFirstObjectUsingBlock: are left as an exercise to the reader
Try this out:->
navController.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor.rawValue: UIColor.red]
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
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
Moshe's first answer didn't work for me because it changed the labels inside of system VCs like mail and text compose VCs. I could change the background of those nav bars but that opens up a whole other can of worms. I didn't want to go the private class route so I only changed UILabels contained inside of my custom navigation bar subclass.
UILabel.appearance(whenContainedInInstancesOf: [NavigationBar.self]).textColor = UIColor.white