I am using UIAppearance to apply fonts to UINavigationBar and UIBarButtonItem and I am having problems. I ran this code:
[[UIBarButtonItem appearanceWhenContainedIn:[UIToolbar class], nil]
setTitleTextAttributes:
@{NSFontAttributeName : [UIFont fontWithName:@"My_Font" size:17.0]}
forState:UIControlStateNormal];
NSLog(@"%@", [[UIBarButtonItem appearanceWhenContainedIn:
[UIToolbar class], nil] titleTextAttributesForState:UIControlStateNormal]);
and the result of that log on iOS 7 is:
(null)
Where the result in iOS 6 is:
{
NSFont = "<UICFFont: 0x1d897a80> font-family: \"My_Font\"; font-weight: normal; font-style: normal; font-size: 17px";
}
I can't find anything in the iOS 7 docs that would indicate that this shouldn't work, has anyone else had this problem?
Edit 1
I actually have gotten this to work with [UINavigationBar appearance]
the problem was that I was setting the point size to 0 in order to have the font be set to the default navbar/barButtonItem size as described in the NSString UIKit Additions Reference but this apparently no longer works in iOS 7. Instead, setting the point size to 0 will return the system font.
I am still unable to set titleTextAttributes
to
[UIBarButtonItem appearanceWhenContaintedIn:[UIToolbar class], nil]]
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont
fontWithName:@"YOURFONT" size:14], NSFontAttributeName,
[UIColor whiteColor], NSForegroundColorAttributeName, nil];
[[UINavigationBar appearance] setTitleTextAttributes:attributes];
The key is to use NSFontAttributeName and so forth. I assume they are moving over to using the NS variety for 64-bit compatibility. The above code worked on my iOS7 device.
Following @Alex Zavatone's answer - it could be done nicely in just one line of code:
self.navBar.titleTextAttributes = @{
NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue-Light" size:20.0],
NSForegroundColorAttributeName: [UIColor redColor]
};
This worked fine for iOS 7 when I moved it to a viewDidLoad method in my view controller.
[[UIBarButtonItem appearance] setTitleTextAttributes:attributes];
When I tried to do this in AppDelegate it didn't work, though[[UINavigationBar appearance] setTitleTextAttributes:setTitleTextAttributes:attributes];
worked fine in AppDelegate. Also it should go before you create and assign the bar button.
It also works from initWithCoder method if you create your bar button on Storyboard.
Update:
If you change deployment target to 7.0 then Xcode will provide you with warnings saying that for example UITextAttributeTextColor is deprecated and you should use NSForegroundColorAttributeName or instead of UITextAttributeFont use NSFontAttributeName. After changing attribute constants you can call setTitleTextAttributes: from AppDelegate.
Here's what I do on iOS-7
UIColor *red = [UIColor colorWithRed:165.0f/255.0f green:1.0f/255.0f blue:0.0f/255.0f alpha:1.0];
UIFont *font = [UIFont fontWithName:@"HelveticaNeue-Light" size:24.0f];
NSMutableDictionary *navBarTextAttributes = [NSMutableDictionary dictionaryWithCapacity:1];
[navBarTextAttributes setObject:font forKey:NSFontAttributeName];
[navBarTextAttributes setObject:red forKey:NSForegroundColorAttributeName ];
self.navBar.titleTextAttributes = navBarTextAttributes;
Here it is in Swift:
let font = UIFont(name: "My_Font", size: 17.0)
UINavigationBar.appearance().titleTextAttributes = [
NSForegroundColorAttributeName: UIColor.whiteColor(),
NSFontAttributeName: font!
]
*Note that you have to unwrap the optional UIFont.
For the UIBarButons use the appearance proxy:
NSDictionary *normalAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:@"Helvetica Neue" size:fontSize], UITextAttributeFont,
nil];
[[UIBarButtonItem appearance] setTitleTextAttributes:normalAttributes
forState:UIControlStateNormal];
If you want to limit which UIBarButtonItems your style affects use appearanceWhenContainedIn: instead.
For the UINavigationBar, you can create a UILabel and set it to your navigationItem.titleView:
UIabel *title = [[UILabel alloc] initWithFrame:CGRectZero];
title.backgroundColor = [UIColor clearColor];
title.font = [*yourfont*];
title.textColor = [*your color*];
self.navigationItem.titleView = title;
Here is how to globally change the nav bar title's text color in Swift 4:
UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor.rawValue: UIColor.yellow]