173

I'm trying to change the back button arrow

enter image description here

I'm currently using the following to control the text size as well as the text color on the back button:

[[UIBarButtonItem appearance] setTitleTextAttributes:
  [NSDictionary dictionaryWithObjectsAndKeys:
    [UIColor whiteColor], UITextAttributeTextColor,
    [UIFont boldSystemFontOfSize:16.0f], UITextAttributeFont,
    [UIColor darkGrayColor], UITextAttributeTextShadowColor,
    [NSValue valueWithCGSize:CGSizeMake(0.0, -1.0)], UITextAttributeTextShadowOffset,
  nil] forState:UIControlStateNormal];

but if I want to change only the arrow's color for the back button, what should i do?

JOM
  • 8,139
  • 6
  • 78
  • 111
kevinl
  • 4,194
  • 6
  • 37
  • 55
  • 1
    Have you found any solution to change arrow's color for the back button? – OnkarK Aug 26 '13 at 10:51
  • 1
    @OMK I ended up changing my infolistproperty NavBarColor to get it to work and then set the actual navbarcolor to a different color. I'm not sure what was going on, but that solution worked for me – kevinl Aug 26 '13 at 14:58
  • 1
    Behavior from some of the properties of `UINavigationBar` has changed from iOS 7. Take a look at the [Answer](http://stackoverflow.com/a/19029973/1603072) to see the effect of some other *Properties* also. – Bhavin Oct 03 '13 at 14:12
  • please help with this problem: http://stackoverflow.com/questions/29923813/ios-back-button-arrow-not-displayed – kresa May 08 '15 at 14:06

17 Answers17

438

To change the back button chevron color for a specific navigation controller*:

self.navigationController.navigationBar.tintColor = [UIColor whiteColor];

*If you are using an app with more than 1 navigation controller, and you want this chevron color to apply to each, you may want to use the appearance proxy to set the back button chevron for every navigation controller, as follows:

[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];

And for good measure, in swift (thanks to Jay Mayu in the comments):

UINavigationBar.appearance().tintColor = UIColor.whiteColor()
DiscDev
  • 38,652
  • 20
  • 117
  • 133
  • 3
    This will only apply throughout the entire app if you are using the same navigation controller for your entire app. I actually recommend Bart's suggestion. – Kyle Clegg Sep 25 '13 at 06:47
  • 1
    I updated my answer with a note about multiple navigation controllers. I still do not agree that Bart's suggestion is the "correct" answer, because there are lots of other side-effects when you set the tint color of the entire app. Plus, the original question did not ask how to theme the entire app, it was only asking how to theme the back button. – DiscDev Sep 25 '13 at 19:18
  • True true. But the reason that I like his answer is that with iOS 7 tinting the entire application is a good design practice and allows for more maintainable code if you want to change that tint color in the future. His answer isn't the exact solution to the problem like yours is, but it helps someone like me move towards Apple's suggested practices. Both are quality answers though. – Kyle Clegg Sep 25 '13 at 21:15
  • 1
    This doesn't seem to set the color of the back chevron. – jcampbell1 Jan 24 '14 at 22:55
  • 2
    @jcampbell1 - I'm using this in several of my apps successfully...perhaps you didn't read the caveat about multiple UINavigationControllers. – DiscDev Jan 27 '14 at 22:17
  • if you want to set this for all controllers, just use the appearance property ;) `[UINavigationBar appearance].tintColor = ...` – geo Mar 24 '14 at 15:44
  • 7
    for swift `UINavigationBar.appearance().tintColor = UIColor.whiteColor()` – Jay Mayu Dec 28 '14 at 17:02
  • 1
    thanks @JayMayu - I'll add this to the answer so it's more complete and give you the credit ;) – DiscDev Dec 30 '14 at 19:49
  • for Swift one can write even shorter UINavigationBar.appearance().tintColor = .whiteColor() – fnc12 Apr 01 '15 at 08:52
  • 1
    also for swift `UINavigationBar.appearance().tintColor = .whiteColor()` – fnc12 Jun 05 '15 at 16:05
  • What you talk about the "appearance proxy", you setting that line of code in the App Delegate right? – Supertecnoboff Nov 06 '15 at 10:50
  • @Supertecnoboff that is definitely a good place to do it. As long as you do it before the UINavigationController that you want to modify is displayed, it will work fine. App Delegate is one place to do it if you want it to apply to the entire navigation based app. – DiscDev Nov 06 '15 at 20:14
  • In iOS 11, it seems you need to set the tint color on the bar button item. `self.navigationItem.backBarButtonItem.tintColor = myColor;` – Tom Hamming Nov 10 '17 at 22:42
57

You have to set the tintColor of the entire app.

self.window.tintColor = [UIColor redColor];

Or in Swift 3:

self.window?.tintColor = UIColor.blue

Source: iOS 7 UI Transition Guide

Bart van Kuik
  • 4,704
  • 1
  • 33
  • 57
  • 4
    If you only want to set the color of the back button chevron (and not the entire app), as stated in the original question, this is the wrong answer. See my answer here for the correct answer: http://stackoverflow.com/a/18809412/1103584 – DiscDev Sep 19 '13 at 19:12
  • I used this in my app delegate to change my back buttons to black. Place in the applicationDidFinishLaunchingWithOptions method... window.tintColor = [UIColor blackColor]; – Marc Watson Oct 14 '13 at 13:17
  • This can't work on iOS 6. Somebody knows what to do ? – Gavjr Oct 17 '13 at 00:31
  • 1
    This caused it to affect the tintColor of the entire app, which includes any UIActivityViewController (for sharing) and the MFMailComposeViewController (for sending email). Those dialogs assume the tintColor hasn't been modified with....and can result in some ugly color interactions. – Mike Lambert Nov 22 '15 at 19:05
  • This changes the tint color of many other objects, such as the blinking cursor in `UITextField`. Definitely not recommended. – Hunter Monk May 05 '16 at 04:57
55

You can set the color on the entire app navigation's bar using the method

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions{
    [[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
}
David Castro
  • 738
  • 4
  • 7
23

It is possible to change only arrow's color (not back button title's color) on this way:

[[self.navigationController.navigationBar.subviews lastObject] setTintColor:[UIColor blackColor]];

Navigation bar contains subview of _UINavigationBarBackIndicatorView type (last item in subviews array) which represents arrow.

Result is navigation bar with different colors of back button arrow and back button title

selma.suvalija
  • 675
  • 9
  • 14
  • 5
    Depending on the order of subviews of system views is a bad idea. – Glenn Maynard Nov 12 '13 at 16:10
  • 2
    this worked, when setting self.navigationController.navigationBar.tintColor did not work. – Rich Fox Jun 19 '14 at 20:28
  • @GlennMaynard You're right—the best way to implement this would be to iterate through the array of subviews returned by `self.navigationController.navigationBar.subviews` until the back button is found. – Evan R Aug 14 '14 at 01:27
  • @EvanR while selmad's solution did work for me, iterating through the array of subviews did not (which I tried first because I agree with you that it would be wise to do so). If it works for you- please add an example. Thanks. – jungledev Aug 26 '15 at 15:56
22

If you are using storyboards you could set the navigation bar tint colour.

enter image description here

enter image description here

ThE uSeFuL
  • 1,456
  • 1
  • 16
  • 29
11

Inside the rootViewController that initializes the navigationController, I put this code inside my viewDidAppear method:

//set back button color
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], UITextAttributeTextColor,nil] forState:UIControlStateNormal];
//set back button arrow color
[self.navigationController.navigationBar setTintColor:[UIColor whiteColor]];
John Riselvato
  • 12,854
  • 5
  • 62
  • 89
7

In iOS 6, tintColor tinted the background of navigation bars, tab bars, toolbars, search bars, and scope bars. To tint a bar background in iOS 7, use the barTintColor property instead.

iOS 7 Design Resources iOS 7 UI Transition Guide

Chamath Jeevan
  • 5,072
  • 1
  • 24
  • 27
  • 2
    This is the one! ... put it in the app delegate. Works like a charm! window.tintColor = [UIColor blackColor]; // I wanted black – Marc Watson Oct 14 '13 at 13:14
6

You can set the tintColor property on the button (or bar button item) or the view controller's view. By default, the property will inherit the tint from the parent view, all the way up to the top level UIWindow of your app.

Mike Weller
  • 45,401
  • 15
  • 131
  • 151
  • 1
    thanks for the response. However, it works a little differently on iOS 7. My old code was using tintColor, but iOS 7 doesn't seem to like it all that much. I ended up using the official Apple Dev iOS 7 transition guide to fix some of the UI issues – kevinl Aug 26 '13 at 14:59
  • See my answer for a discrete example of how to do this: http://stackoverflow.com/a/18809412/1103584 – DiscDev Sep 19 '13 at 19:12
5

I had to use both:

[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] 
                     setTitleTextAttributes:[NSDictionary 
               dictionaryWithObjectsAndKeys:[UIColor whiteColor], UITextAttributeTextColor,nil] 
                                   forState:UIControlStateNormal];

[[self.navigationController.navigationBar.subviews lastObject] setTintColor:[UIColor whiteColor]];

And works for me, thank you for everyone!

Robert
  • 5,278
  • 43
  • 65
  • 115
Márcia Silva
  • 61
  • 1
  • 2
5
UINavigationBar *nbar = self.navigationController.navigationBar;

if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
   //iOS 7
   nbar.barTintColor = [UIColor blueColor]; // bar color
   //or custom color 
   //[UIColor colorWithRed:19.0/255.0 green:86.0/255.0 blue:138.0/255.0 alpha:1];

   nbar.navigationBar.translucent = NO;

   nbar.tintColor = [UIColor blueColor]; //bar button item color

} else {
   //ios 4,5,6
   nbar.tintColor = [UIColor whiteColor];
   //or custom color
   //[UIColor colorWithRed:19.0/255.0 green:86.0/255.0 blue:138.0/255.0 alpha:1];

}
MD SHAHIDUL ISLAM
  • 14,325
  • 6
  • 82
  • 89
5

Update Swift 3

navigationController?.navigationItem.rightBarButtonItem?.tintColor = UIColor.yellow
navigationController?.navigationBar.tintColor = UIColor.red
navigationController?.navigationBar.barTintColor = UIColor.gray
navigationController?.navigationBar.titleTextAttributes =  [NSForegroundColorAttributeName: UIColor.blue]

Result: enter image description here

Ricardo Mutti
  • 2,639
  • 2
  • 19
  • 20
3

Just to change the NavigationBar color you can set the tint color like below.

[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
chx
  • 11,270
  • 7
  • 55
  • 129
  • This won't affect the tint color in iOS 7. According to the docs: "Setting the tintColor property by using the appearance proxy APIs is not supported in iOS 7." [link](https://developer.apple.com/library/prerelease/ios/documentation/UserExperience/Conceptual/TransitionGuide/AppearanceCustomization.html) – bachonk Mar 04 '14 at 18:00
3

In case you're making custom back button basing on UIButton with image of arrow, here is the subclass snippet. Using it you can either create button in code or just assign class in Interface Builder to any UIButton. Back Arrow Image will be added automatically and colored with text color.

@interface UIImage (TintColor)

- (UIImage *)imageWithOverlayColor:(UIColor *)color;

@end


@implementation UIImage (TintColor)

- (UIImage *)imageWithOverlayColor:(UIColor *)color
{
    CGRect rect = CGRectMake(0.0f, 0.0f, self.size.width, self.size.height);

    if (UIGraphicsBeginImageContextWithOptions) {
        CGFloat imageScale = 1.0f;
        if ([self respondsToSelector:@selector(scale)])
            imageScale = self.scale;
        UIGraphicsBeginImageContextWithOptions(self.size, NO, imageScale);
    }
    else {
        UIGraphicsBeginImageContext(self.size);
    }

    [self drawInRect:rect];

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetBlendMode(context, kCGBlendModeSourceIn);

    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

@end




#import "iOS7backButton.h"

@implementation iOS7BackButton

-(void)awakeFromNib
{
    [super awakeFromNib];

    BOOL is6=([[[UIDevice currentDevice] systemVersion] floatValue] <7);
    UIImage *backBtnImage = [[UIImage imageNamed:@"backArrow"] imageWithOverlayColor:self.titleLabel.textColor];
    [self setImage:backBtnImage forState:UIControlStateNormal];
    [self setTitleEdgeInsets:UIEdgeInsetsMake(0, 5, 0, 0)];
    [self setImageEdgeInsets:UIEdgeInsetsMake(0, is6?0:-10, 0, 0)];


}


+ (UIButton*) buttonWithTitle:(NSString*)btnTitle andTintColor:(UIColor*)color {
    BOOL is6=([[[UIDevice currentDevice] systemVersion] floatValue] <7);
    UIButton *backBtn=[[UIButton alloc] initWithFrame:CGRectMake(0, 0, 60, 30)];
    UIImage *backBtnImage = [[UIImage imageNamed:@"backArrow"] imageWithOverlayColor:color];
    [backBtn setImage:backBtnImage forState:UIControlStateNormal];
    [backBtn setTitleEdgeInsets:UIEdgeInsetsMake(0, is6?5:-5, 0, 0)];
    [backBtn setImageEdgeInsets:UIEdgeInsetsMake(0, is6?0:-10, 0, 0)];
    [backBtn setTitle:btnTitle forState:UIControlStateNormal];
    [backBtn setTitleColor:color /*#007aff*/ forState:UIControlStateNormal];

    return backBtn;
}

@end

back button image@2x

Eugene Braginets
  • 856
  • 6
  • 16
3

If you want to change only the Back Arrow BUT on the entire app, do this:

[[NSClassFromString(@"_UINavigationBarBackIndicatorView") appearance] 
  setTintColor:[UIColor colorWithHexString: @"#f00000"]];
orkenstein
  • 2,810
  • 3
  • 24
  • 45
  • Theres a chance this would get you rejected from the app store – Luke Feb 06 '15 at 05:29
  • @Luke, I've successfully used it several times. No rejections. But, yep, chance still exist. – orkenstein Feb 06 '15 at 06:51
  • It is still likely it will get broken in future iOS version – Lope Feb 14 '15 at 16:46
  • 1
    @Lope, yes, why not. I'm not looking for silver bullet. – orkenstein Feb 14 '15 at 17:32
  • Iterating through the subviews on iOS 10.1 shows that that is still the class name, but setting its appearance as shown here is having no effect for me. – arlomedia Dec 15 '16 at 22:52
  • @arlomedia, it might break. Try to examine the whole hierarchy. – orkenstein Dec 16 '16 at 11:31
  • I looked at all the subviews of the UINavigationBar, and all the subviews of those subviews (the _UINavigationBarBackIndicatorView has no subviews) but didn't see anything helpful. BTW, I tried adding the tintColor directly to the _UINavigationBarBackIndicatorView and other subviews. That kind of worked, but the color flashed off and on when navigating. – arlomedia Dec 16 '16 at 23:24
2

In iOS 7, you can put the following line of code inside application:didFinishLaunchingWithOptions: in your AppDelegate.m file:

[[UINavigationBar appearance] setTintColor:myColor];

Set myColor to the color you want the back button to be throughout the entire app. No need to put it in every file.

eritbh
  • 726
  • 1
  • 9
  • 18
0

Swift 2.0: Coloring Navigation Bar & buttons

navigationController?.navigationBar.barTintColor = UIColor.blueColor()
navigationController?.navigationBar.tintColor = UIColor.whiteColor()
navigationController!.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor()]
AbhinayMe
  • 2,399
  • 1
  • 20
  • 21
0

In swift 3 , to change UIBarButton back button arrow color

self.navigationController?.navigationBar.tintColor = UIColor.black
Dilip Jangid
  • 754
  • 1
  • 10
  • 20