90

I have a multiple View Controllers and I want to set the font color of all to red.

 [[UINavigationBar appearance] setFont:[UIFont boldSystemFontOfSize:12.0]];

is throwing an unrecognized selector error.

How can I fix this?

halfer
  • 19,824
  • 17
  • 99
  • 186
carbonr
  • 6,049
  • 5
  • 46
  • 73

7 Answers7

206

From Ray Wenderlich:

http://www.raywenderlich.com/4344/user-interface-customization-in-ios-5

// Customize the title text for *all* UINavigationBars
[[UINavigationBar appearance] setTitleTextAttributes:
    [NSDictionary dictionaryWithObjectsAndKeys:
        [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0], 
        UITextAttributeTextColor, 
        [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8], 
        UITextAttributeTextShadowColor, 
        [NSValue valueWithUIOffset:UIOffsetMake(0, -1)], 
        UITextAttributeTextShadowOffset, 
        [UIFont fontWithName:@"Arial-Bold" size:0.0], 
        UITextAttributeFont, 
        nil]];

Or if you prefer with the object literal style:

[[UINavigationBar appearance] setTitleTextAttributes:@{
    UITextAttributeTextColor: [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0],
    UITextAttributeTextShadowColor: [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],
    UITextAttributeTextShadowOffset: [NSValue valueWithUIOffset:UIOffsetMake(0, -1)],
    UITextAttributeFont: [UIFont fontWithName:@"Arial-Bold" size:0.0],
}];

Edit for iOS 7 and following

UITextAttributes are deprecate as iOS 7 you can use the following :

NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor colorWithWhite:.0f alpha:1.f];
shadow.shadowOffset = CGSizeMake(0, -1);

[[UINavigationBar appearance] setTitleTextAttributes:@{
     NSForegroundColorAttributeName: [UIColor whiteColor],
     NSShadowAttributeName: shadow,
     NSFontAttributeName: [UIFont fontWithName:@"Arial-Bold" size:15.0f]
     }];
mt81
  • 3,288
  • 1
  • 26
  • 35
TigerCoding
  • 8,710
  • 10
  • 47
  • 72
  • 1
    For over 1 hour, I was struggling with that part of code from the tutorial, which leads cropping my navigation item's title after the first push... Be careful with the font size, which was the problem in my situation... Apparently size 0.0 did not work for me... – Bartu Jan 12 '13 at 17:14
  • 3
    the new dictionary literal will make this a lot prettier – tybro0103 Apr 24 '13 at 15:42
  • Just as a side note this is 5.0+ only, if you're supporting 4 then it's worth doing `if ([navBarInstance respondsToSelector:@selector(appearance)])` first because it will crash iOS versions below 5. – Adam Waite Sep 18 '13 at 09:21
  • meant `[UINavigationBar class]` rather than `navBarInstance` – Adam Waite Sep 18 '13 at 09:33
  • 1
    The font name is wrong and crashes the app. Try something like Arial-BoldMT. – MacMark Sep 18 '13 at 17:02
  • condensed sample: `[[UINavigationBar appearance] setTitleTextAttributes: @{UITextAttributeTextColor : [UIColor whiteColor]}];` – Brenden Oct 07 '13 at 20:02
  • 17
    TIL `UITextAttributeTextColor` is deprecated in favor of `NSForegroundColorAttributeName` in iOS 7 – Brenden Oct 08 '13 at 00:13
  • I have been looking for the proper answer to this question for months. You are a hero. – M. Ryan Dec 17 '13 at 18:04
  • `UITextAttributeFont` is also deprecated,use `NSFontAttributeName` instead. – tounaobun Jul 02 '15 at 02:57
  • The iOS 7 version works on iOS 9 .Just need to add `fontWithName:@"Arial-BoldMT"` instead of `fontWithName:@"Arial-Bold"` – iCodes May 04 '16 at 11:57
23

For deployment targets greater than or equal to iOS 6, you should use NSShadow instead:

NSShadow * shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor lightGrayColor];
shadow.shadowOffset = CGSizeMake(0, -2);

NSDictionary * navBarTitleTextAttributes =
@{ NSForegroundColorAttributeName : [UIColor redColor],
   NSShadowAttributeName          : shadow,
   NSFontAttributeName            : [UIFont systemFontOfSize:14] };

[[UINavigationBar appearance] setTitleTextAttributes:navBarTitleTextAttributes];

enter image description here

Robert
  • 37,670
  • 37
  • 171
  • 213
19

Doing this on iOS 8+ and in Swift. There isn't a setTitleTextAttributes for the appearance object. Instead, do this:

UINavigationBar.appearance().titleTextAttributes = [NSFontAttributeName : AppTheme.fontWithSize(18)]
Matthew Quiros
  • 13,385
  • 12
  • 87
  • 132
5

I did this by adding just few lines of code in AppDelegate.m class didFinishLaunchingWithOptions method: Use this code:

NSDictionary *navbarTitleTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                           [UIColor colorWithRed:255.0f/255.0f green:0.0f/255.0f blue:0.0f/255.0f alpha:1.0],UITextAttributeTextColor,
                                           [UIColor clearColor], UITextAttributeTextShadowColor,
                                           [NSValue valueWithUIOffset:UIOffsetMake(-1, 0)], UITextAttributeTextShadowOffset, nil];

[[UINavigationBar appearance] setTitleTextAttributes:navbarTitleTextAttributes];

it works for me...

Maishi Wadhwani
  • 1,104
  • 15
  • 24
5

If you need to do this in Swift, you can create an extension for the UINavigationBar to allow you to get or set these settings.

extension UINavigationBar {
var titleColor: UIColor? {
    get {
        if let attributes = self.titleTextAttributes {
            return attributes[NSForegroundColorAttributeName] as? UIColor
        }
        return nil
    }
    set {
        if let value = newValue {
            self.titleTextAttributes = [NSForegroundColorAttributeName: value]
        }
    }
}

var titleFont: UIFont? {
    get {
        if let attributes = self.titleTextAttributes {
            return attributes[NSFontAttributeName] as? UIFont
        }
        return nil
    }
    set {
        if let value = newValue {
            self.titleTextAttributes = [NSFontAttributeName: value]
        }
    }
    }
}

You can then set the color and font like this:

navigationBar.titleColor = UIColor.redColor()
navigationBar.titleFont = UIFont.systemFontOfSize(12)
totiDev
  • 5,189
  • 3
  • 30
  • 30
  • I guess this solution works if you use either `titleColor` or `titleFont` individually. If you use them together, the `self.titleTextAttributes` will be set to a new value every time one of the variables is called. The setter could probably get the other value when it creates the new dictionary. – user023 Nov 27 '18 at 17:12
1

This could be used to set a custom view to a single navigationBar instead of a global setting

- (void)updateTitleWithString:(NSString *)title
{
    UIView *headerView = [[UIView alloc] initWithFrame:CGRectZero];
    [headerView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
    [headerView setAutoresizesSubviews:YES];

    CGFloat headFontSize = (IS_SYSTEM_DEVICE_IPAD ? 25.0f : 19.0f);
    UIFont *headFont = [UIFont boldSystemFontOfSize: headFontSize ];

    NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    [style setLineBreakMode:NSLineBreakByTruncatingTail];

    CGSize size = [title boundingRectWithSize:CGSizeMake(190,headFontSize + 6) options:NSStringDrawingUsesLineFragmentOrigin
                                   attributes:@{NSFontAttributeName : headFont, NSParagraphStyleAttributeName : style} context:nil].size;

    headerView.frame  = CGRectMake(0, 0,size.width,self.navigationController.navigationBar.frame.size.height);
    float labelHeight = headFontSize + 6;
    float labelYLoc   = (   self.navigationController.navigationBar.frame.size.height - labelHeight ) / 2;
    UILabel *label    = [[UILabel alloc] initWithFrame:CGRectMake(0,labelYLoc, size.width,labelHeight)];
    label.backgroundColor = [UIColor clearColor];
    label.adjustsFontSizeToFitWidth = YES;
    label.textAlignment = NSTextAlignmentCenter;
    label.textColor = [UIColor whiteColor];
    label.font = headFont;
    label.text = title;
    label.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.4];
    label.lineBreakMode = NSLineBreakByTruncatingTail;
    label.shadowOffset = CGSizeMake(0,-1);
    label.accessibilityLabel = @"<LABEL>";
    [headerView addSubview:label];

    self.navigationItem.titleView = headerView;
}
leokash
  • 200
  • 1
  • 6
-5

Use this line of code

UILabel *badge_Label=[[UILabel alloc]initWithFrame:CGRectMake(5,3, 15, 15)];
badge_Label.backgroundColor=[UIColor redcolor];
badge_Label.font=[UIFont systemFontOfSize:12];
[badge_Label setText:@"20"];
[self.navigationController.navigationBar addSubview:badgelabel];

I think this will be helpful for you.

vishiphone
  • 750
  • 7
  • 14