titleTextAttributes UIAppearance font in iOS 7

2019-01-17 02:58发布

问题:

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

回答1:

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.



回答2:

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


回答3:

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.



回答4:

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;


回答5:

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.



回答6:

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;


回答7:

Here is how to globally change the nav bar title's text color in Swift 4:

UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor.rawValue: UIColor.yellow]