27

I'm trying to change the font color of the text on my back button in my UINavigationControllerBar:

[[UIBarButtonItem appearance] setTitleColor:[UIColor redColor] forState:UIControlStateNormal];

I get this error:

[_UIBarItemAppearance setTitleColor:forState:]: unrecognized selector sent to instance 0x69aeb70'
Salvatore
  • 10,815
  • 4
  • 31
  • 69
itgiawa
  • 1,616
  • 4
  • 16
  • 28

5 Answers5

50
NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
[attributes setValue:[UIColor colorWithRed:(163.0f/255.0f) green:(0.0f) blue:(0.0f) alpha:1.0f] forKey:UITextAttributeTextColor];
[attributes setValue:[UIColor clearColor] forKey:UITextAttributeTextShadowColor];
[attributes setValue:[NSValue valueWithUIOffset:UIOffsetMake(0.0, 0.0)] forKey:UITextAttributeTextShadowOffset];
[[UIBarButtonItem appearance] setTitleTextAttributes:attributes forState:UIControlStateNormal];

seems to work!

itgiawa
  • 1,616
  • 4
  • 16
  • 28
  • 2
    Way better solution to use the appearance options. They work globally, or by class, or by instance. Anyone coming here should use this answer instead. – Heckman Sep 12 '13 at 18:22
  • Depends fully on the situation. I was working on a game and needed to change the font only temporally. ;-) – phikes Jan 26 '14 at 12:34
  • 3
    [[UIBarButtonItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0], NSForegroundColorAttributeName, [UIFont fontWithName:@"Cuprum-regular" size:14.0], NSFontAttributeName, nil] forState:UIControlStateNormal]; – Genevios Aug 19 '15 at 16:31
  • Its more dam perfectly change font – Genevios Aug 19 '15 at 16:31
18
[[UIBarButtonItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
                                                     [UIFont fontWithName:kDefaultFont size:16.0f],UITextAttributeFont,
                                                     nil] forState:UIControlStateNormal];
Paulius Vindzigelskis
  • 2,121
  • 6
  • 29
  • 41
15

Use this instead, default function available in iOS 5:

UIBarButtonItem *backbutton = [[UIBarButtonItem alloc] initWithTitle:@"back" style:UIBarButtonItemStyleBordered target:nil action:nil];

[backbutton setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
    [UIColor blackColor],UITextAttributeTextColor,
    [UIFont fontWithName:TEXTFONT size:16.0f],UITextAttributeFont,nil]
    forState:UIControlStateNormal]; 
McKinley
  • 1,123
  • 1
  • 8
  • 18
Ranjit
  • 4,576
  • 11
  • 62
  • 121
6

And the beautiful solution, iOS7+ (because of attribute names):

NSShadow *shadow = [NSShadow new];
[shadow setShadowColor: [UIColor colorWithWhite:0.0f alpha:0.750f]];
[shadow setShadowOffset: CGSizeMake(0.0f, 1.0f)];

[[UIBarButtonItem appearance] setTitleTextAttributes:@{
        NSFontAttributeName: [UIFont systemFontOfSize:24],
        NSForegroundColorAttributeName: [UIColor colorWithWhite:0.2 alpha:1.0],
        NSShadowAttributeName: shadow,
} forState:UIControlStateNormal];
Eugene Tartakovsky
  • 1,594
  • 17
  • 22
3

Solution in Swift 4:

UIBarButtonItem.appearance().setTitleTextAttributes(
[
    NSAttributedStringKey.font: UIFont(name: "MyriadPro-SemiboldCond", size: 16)!,
    NSAttributedStringKey.foregroundColor: UIColor.white
], for: .normal)

Add this in AppDelegate and it'll be applied to all buttons in the app.

Makalele
  • 7,431
  • 5
  • 54
  • 81
  • Seem to have a bug that only applies the font to the seconds time viewing the button. Seems to still exist in iOS 12. – Sunkas Feb 28 '19 at 07:41