I'm using the new enlarged navigation bar titles in iOS 11. But I can't seem to be able to change the textColor.
I tried doing:
self.navigationController.navigationBar.titleTextAttributes = #{NSForegroundColorAttributeName: [UIColor whiteColor]};
This didn't do anything. Any ideas?
self.navigationController.navigationBar.largeTitleTextAttributes = #{NSForegroundColorAttributeName: [UIColor whiteColor]};
I think it's still a bug in Xcode 9 beta 6.
I found different "solutions" for it:
It's possible to change the color of the title if you put this in the AppDelegate:
if #available(iOS 11.0, *) {
UINavigationBar.appearance().largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.blue]
}
Other way is to set the color in your Controller's viewDidLoad, but the secret to make it work is to set the font also:
if #available(iOS 11.0, *) {
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.blue, NSAttributedStringKey.font: UIFont.systemFont(ofSize: 31, weight: UIFont.Weight.bold) ]
}
Hope it helps you.
Regards!
iOS 11
Objective-C
if (#available(iOS 11.0, *)) {
self.navigationController.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAlways;
self.navigationController.navigationBar.prefersLargeTitles = true;
// Change Color
self.navigationController.navigationBar.largeTitleTextAttributes = #{NSForegroundColorAttributeName: [UIColor whiteColor]};
} else {
// Fallback on earlier versions
}
Swift 5.6.1
In my Swift 5.6.1 and iOS 15.6.1 the following code worked only.
Add the following codes in ViewDidLoad()
let appearance = UINavigationBarAppearance(idiom: .phone)
// Add the color you want in your title
appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
appearance.titleTextAttributes = [.foregroundColor: UIColor.white]
// Add the color you want as your navigation bar color. Otherwise it shows White by default
appearance.backgroundColor = .purple
navigationItem.standardAppearance = appearance
navigationItem.scrollEdgeAppearance = appearance
Swift 4.2
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
with named color
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor(named: "Teal") ?? UIColor.black]
Swift up through Swift 3.2 (not Swift 4+)
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
let largeTitleTextAttributes: [NSAttributedString.Key: Any] = [.foregroundColor: UIColor.gray20, .font: UIFont.systemFont(ofSize: 24.0, weight: .bold)]
if #available(iOS 15, *) {
let navigationBar = navigationController.navigationBar
let appearance = navigationBar.standardAppearance
appearance.largeTitleTextAttributes = largeTitleTextAttributes
navigationBar.standardAppearance = appearance
navigationBar.scrollEdgeAppearance = appearance
} else {
navigationController.navigationBar.largeTitleTextAttributes = largeTitleTextAttributes
}
Related
Since I upgraded my iPad operating system, the title of the UITabBar of my app is showing truncated, as shown in the screenshot.
I have tried some methods, but I have not found the correct solution.
Hope someone can help me.
And Here is code:
func setupTabBar() {
if #available(iOS 13, *) {
let appearance = tabBar.standardAppearance
appearance.configureWithOpaqueBackground()
appearance.backgroundImage = UIImage(color: .white)
appearance.shadowImage = UIImage(color: .clear)
let normalAttrs: [NSAttributedString.Key: Any] = [.foregroundColor: ThemeColor.gray]
let selectedAttrs: [NSAttributedString.Key: Any] = [.foregroundColor: ThemeColor.red]
appearance.stackedLayoutAppearance.selected.titleTextAttributes = selectedAttrs
appearance.stackedLayoutAppearance.normal.titleTextAttributes = normalAttrs
appearance.inlineLayoutAppearance.selected.titleTextAttributes = selectedAttrs
appearance.inlineLayoutAppearance.normal.titleTextAttributes = normalAttrs
appearance.compactInlineLayoutAppearance.selected.titleTextAttributes = selectedAttrs
appearance.compactInlineLayoutAppearance.normal.titleTextAttributes = normalAttrs
UITabBar.appearance().standardAppearance = appearance
} else {
tabBar.backgroundImage = UIImage(color: .white)
tabBar.shadowImage = UIImage(color: .clear)
}
if #available(iOS 15, *) {
UITabBar.appearance().scrollEdgeAppearance = UITabBar.appearance().standardAppearance
}
}
For some reason, it seems that setting the titleTextAttributes is what causes the problem to happen with inlineLayoutAppearance, and including the default paragraph style of NSParagraphStyle.default fixes it.
For your code, the following changes should fix it (as of iOS 15.0).
let normalAttrs: [NSAttributedString.Key: Any] = [.foregroundColor: ThemeColor.gray, .paragraphStyle: NSParagraphStyle.default]
let selectedAttrs: [NSAttributedString.Key: Any] = [.foregroundColor: ThemeColor.red, .paragraphStyle: NSParagraphStyle.default]
For those that cannot have a default paragraph style, setting the attributes for most States got the OS to size the labels correctly for me.
Swift 5.0:
UITabBarItem.appearance()
.setTitleTextAttributes(
customAttributesWithCustomParagraphStyle,
for: [
.normal,
.highlighted,
.disabled,
.selected,
.focused,
.application,
]
)
Without setting it for at least .normal and .selected, the UITabBarItem title gets truncated when used with custom attributes.
I’m using Xcode 11.4 and iOS 13.4.
I have set navigation bar title custom font using UINavigatinBar.appearance()
And it works correctly but on iOS 13+ when i try to push to another VC and then comeback to the parent VC, the parent VC title font suddenly has been set to default font and after a second it changes back to the custom font.
Below is a gif of the problem:
nav bar font problem
iOS 13.+ has UINavigationBarAppearance approach to customize NavigationBar-Title & NavigationBar-BarButtonItems
Check this code, might help you
let titleFontAttrs = [ NSAttributedString.Key.font: UIFont(name: "custom-font-name", size: 20)!, NSAttributedString.Key.foregroundColor: UIColor.white ]
let barButtonFontAttrs = [ NSAttributedString.Key.font: UIFont(name: "custom-font-name", size: 14)! ]
UINavigationBar.appearance().tintColor = UIColor.white // bar icons
if #available(iOS 13.0, *) {
let appearance = UINavigationBarAppearance()
appearance.backgroundColor = .red // If you want different nav background color other than white
appearance.titleTextAttributes = titleFontAttrs
appearance.largeTitleTextAttributes = titleFontAttrs // If your app supports largeNavBarTitle
UINavigationBar.appearance().isTranslucent = false
appearance.buttonAppearance.normal.titleTextAttributes = barButtonFontAttrs
appearance.buttonAppearance.highlighted.titleTextAttributes = barButtonFontAttrs
UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().compactAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = appearance
} else {
UINavigationBar.appearance().barTintColor = .red // bar background
UINavigationBar.appearance().titleTextAttributes = titleFontAttrs
UINavigationBar.appearance().isTranslucent = false
UIBarButtonItem.appearance().setTitleTextAttributes(barButtonFontAttrs, for: .normal)
UIBarButtonItem.appearance().setTitleTextAttributes(barButtonFontAttrs, for: .highlighted)
}
Here you go, manage it in viewDidAppear:
let lblTitle = UILabel()
let titleAttribute: [NSAttributedString.Key: Any] = [.font: UIFont.boldSystemFont(ofSize: 21),
.foregroundColor: UIColor.black]
let attributeString = NSMutableAttributedString(string: "Navigation Title", attributes: titleAttribute)
lblTitle.attributedText = attributeString
lblTitle.sizeToFit()
navigationItem.titleView = lblTitle
UIBarButtonItem.appearance().setTitleTextAttributes() doesn't work on iOS 13.
The way iOS handles global appearances appears to have changed. You'll need to add a condition check for iOS 13 and above and then add your attributes as shown below.
if #available(iOS 13.0, *) {
let standard = UINavigationBarAppearance()
standard.configureWithTransparentBackground()
// TITLE STYLING
standard.titleTextAttributes = [.foregroundColor: UIColor.white, .font: "FONTNAME"]
// NAV BUTTON STYLING
let button = UIBarButtonItemAppearance(style: .plain)
button.normal.titleTextAttributes = [.foregroundColor: .white, .font: "FONTNAME"]
standard.buttonAppearance = button
let done = UIBarButtonItemAppearance(style: .done)
done.normal.titleTextAttributes = [.foregroundColor: .white, .font: "FONTNAME"]
standard.doneButtonAppearance = done
UINavigationBar.appearance().standardAppearance = standard
} else {
// Your previous styling here for 12 and below
}
Check out this post for more. I found it really useful in understanding the new updates.
I have a problem with the color of my UITabBarItems when I run on iOS 13 simulators, using Xcode 11, beta 2. I have made a sample project from scratch, and everything works correctly when I do not specify a bar tint color. However, when I do specify a custom bar tint color via Interface Builder, I get this:
All items icons in the tab bar have the selected color if I set the "Bar Tint" property in Interface Builder to anything but clear. When it is set to clear, the icons are colored properly. The icons are also colored properly if I compile and run in an iOS 12 simulator.
This seems like a bug in Xcode 11, but maybe I'm missing something?
There is a new appearance API in iOS 13. To color tabbar item's icon and text correctly using Xcode 11.0 you can use it like this:
if #available(iOS 13, *) {
let appearance = UITabBarAppearance()
appearance.backgroundColor = .white
appearance.shadowImage = UIImage()
appearance.shadowColor = .white
appearance.stackedLayoutAppearance.normal.iconColor = .black
appearance.stackedLayoutAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
appearance.stackedLayoutAppearance.normal.badgeBackgroundColor = .blue
appearance.stackedLayoutAppearance.selected.iconColor = .red
appearance.stackedLayoutAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.red]
self.tabBar.standardAppearance = appearance
}
On the surface, this might seem like a bug, however you can mitigate it by defining an .unselectedItemTintColor on your UITabBar instance.
self.tabBar.unselectedItemTintColor = [UIColor lightGrayColor];
Use the attribute field "Image Tint" in IB.
For Objective C you can use in AppDelegate:
[[UITabBar appearance] setTintColor:[UIColor whiteColor]];
[[UITabBar appearance] setUnselectedItemTintColor:[UIColor colorWithRed:255.0f/255.0f green:255.0f/255.0f blue:255.0f/255.0f alpha:0.65f]];
if #available(iOS 13.0, *) {
let appearance = tabBar.standardAppearance
appearance.stackedLayoutAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
appearance.stackedLayoutAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.blue]
appearance.stackedLayoutAppearance.normal.iconColor = UIColor.black
appearance.stackedLayoutAppearance.selected.iconColor = UIColor.blue
tabBar.standardAppearance = appearance
} else {
tabBar.unselectedItemTintColor = UIColor.black
tabBar.tintColor = UIColor.blue
}
Thanks for Samuël's answer. Here is the UITabBar setting in my app, it is 2021 already but still rare helpful information in internet about how to set UITabBar for iOS 13 and above.
if #available(iOS 13, *) {
let appearance = UITabBarAppearance()
// appearance.backgroundColor = .white
appearance.shadowImage = UIImage()
appearance.shadowColor = .white
appearance.stackedLayoutAppearance.normal.iconColor = .gray
appearance.stackedLayoutAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.gray]
// appearance.stackedLayoutAppearance.normal.badgeBackgroundColor = .yellow
appearance.stackedLayoutAppearance.selected.iconColor = .systemPink
appearance.stackedLayoutAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.systemPink]
// set padding between tabbar item title and image
appearance.stackedLayoutAppearance.selected.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 4)
appearance.stackedLayoutAppearance.normal.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 4)
self.tabBar.standardAppearance = appearance
} else {
// set padding between tabbar item title and image
UITabBarItem.appearance().titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 4)
UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.gray], for: .normal)
UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.systemPink], for: .selected)
}
self.tabBarController?.tabBar.unselectedItemTintColor = UIColor.lightGray
This works for me in swift 4. Just put this in the override func viewWillDisappear(_ animated: Bool) method and this will update as the view is changing.
So it will look something like this
override func viewWillDisappear(_ animated: Bool) {
self.tabBarController?.tabBar.unselectedItemTintColor = UIColor.lightGray
}
Even if this is a bug(I'm not sure) you can use this to change the color of the tab bar item by using any color of you choice
When developing in swift 3 I was used to write:
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName: UIColor.orange]
putting this in AppDelegate would change all the UINavbars' title color to orange.
Now I want to do the same with Swift 4 and iOS 11.
You can change the UINavigationBar title color by setting the foregroundColor property on titleTextAttributes.
As documented here:
The titleTextAttributes property specifies the attributes for
displaying the bar’s title text. You can specify the font, text color,
text shadow color, and text shadow offset for the title in the text
attributes dictionary using the font , foregroundColor , and shadow
keys, respectively.
So you will have the same effect doing this:
UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor.rawValue: UIColor.orange]
Swift 4.1 Changing navigation bar title color
if #available(iOS 11.0, *) {
//To change iOS 11 navigationBar largeTitle color
UINavigationBar.appearance().prefersLargeTitles = true
UINavigationBar.appearance().largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
} else {
// for default navigation bar title color
UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
}
Swift 4.2+ Changing navigation bar title color
if #available(iOS 11.0, *) {
//To change iOS 11 navigationBar largeTitle color
UINavigationBar.appearance().prefersLargeTitles = true
UINavigationBar.appearance().largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
} else {
// for default navigation bar title color
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
}
App delegate swift 4.2
UINavigationBar.appearance().barTintColor = UIColor.white
UINavigationBar.appearance().tintColor = UIColor(hex: 0xED6E19)
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor(hex: 0xED6E19)]
Swift 4
UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey(rawValue: NSAttributedStringKey.foregroundColor.rawValue): UIColor.orange]
Swift 4 implementation for both large and regular titles:
extension UINavigationController {
func setTitleForgroundTitleColor(_ color: UIColor) {
self.navigationBar.titleTextAttributes = [NSAttributedStringKey(rawValue: NSAttributedStringKey.foregroundColor.rawValue): color]
}
func setLargeTitleColor(_ color: UIColor) {
self.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey(rawValue: NSAttributedStringKey.foregroundColor.rawValue): color]
}
func setAllTitleColor(_ color: UIColor) {
setTitleForgroundTitleColor(color)
setLargeTitleColor(color)
}
}
You can change the navigation bar title color by using this code
navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
Swift 4.2
fileprivate func convertToOptionalNSAttributedStringKeyDictionary(_ input: [String: Any]?) -> [NSAttributedString.Key: Any]? {
guard let input = input else { return nil }
return Dictionary(uniqueKeysWithValues: input.map { key, value in (NSAttributedString.Key(rawValue: key), value)})
}
Usage
// Set Navigation bar Title color
UINavigationBar.appearance().titleTextAttributes = convertToOptionalNSAttributedStringKeyDictionary([NSAttributedString.Key.foregroundColor.rawValue : UIColor.white])
For Swift 5 if Someone is Looking around like I was :
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor(displayP3Red: 84/255, green: 93/255, blue: 118/255, alpha: 1)]