How can I customize the text color of the back button in a UINavigationController header view?

I'm using a custom tintColor on my UINavigationController's navigation bar, and because the color is so light I need to use dark colored text. It's relatively easy to swap out the title view, and the custom buttons I've added on the right hand side, but I can't seem to get a custom view to stick on the back button. This is what I'm trying right now:

    UILabel *backLabel = [[UILabel alloc] initWithFrame:CGRectZero];

    [backLabel setFont:[UIFont fontWithName:[[UIFont fontNamesForFamilyName:@"Arial Rounded MT Bold"] objectAtIndex:0] size:24.0]];
    [backLabel setTextColor:[UIColor blackColor]];
    [backLabel setShadowColor:[UIColor clearColor]];

    [backLabel setText:[aCategory displayName]];
    [backLabel sizeToFit];
    [backLabel setBackgroundColor:[UIColor clearColor]];

    UIBarButtonItem *temporaryBarButtonItem=[[UIBarButtonItem alloc] initWithCustomView:backLabel];

    temporaryBarButtonItem.customView = backLabel;
    [backLabel release];

    self.navigationItem.backBarButtonItem = temporaryBarButtonItem;
    [temporaryBarButtonItem release];]

The custom view doesn't stick though, and I don't see any obviously easy way to get at the actual text inside the default button and start changing its style.

Answers


There's no official way to do this. The two methods that I could think of are:

  • navigate the view tree to find the existing Back button, and set its text color manually. This is probably not a good idea, as it's fragile, and the button may not even have a configurable textColor property.

  • create your own back button (ie, with your own image), and set its color. This is what we do in a number of places. It's a little more work, but the results are exactly what you want.


This works, solves the original question (change the Navbar BACK button - and no buttons on other toolbars, no buttons on tab bars, etc):

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

I tried traversing to set the text, but it ends ups on a UINavigationItemButtonView, which appears to just draw directly. There is no way to set the color.

The only way I was able to get it to work is to convert the text into an image, and then set the back button to the image.

UIBarButtonItem * backItem = [[UIBarButtonItem alloc] initWithImage:backImage style:UIBarButtonItemStylePlain target:nil action:nil];
navItem.backBarButtonItem = backItem;
[backItem release];

SkotchV is correct. In previous versions of the SDK, they used distinct UIButton instances, which allowed customizing by traversing the subview hierarchy. It is no longer possible.


@DrMickeyLauer Iterating the hierarchy to set the text color is possible in my development environment. When you populate your UINavigationBar's left and right views, your UINavigationBar will have UIButtons as subviews. If you're getting fancy and parenting UIToolbars to your navigation bar, you can iterate through your navBar.items, checking for UINavigationItems (via isKindOfClass:). These navigation items have left and right item arrays. These arrays contain (among other things) the toolbar(s) you put in the navigation bar's left and right views. These left and right arrays give you access to the toolbar's UIBarButtonItems. You can then call setTitleTextAttributes on the UIBarButtonItems to set their text and shadow colors.

But, as Ben Gottlieb stated, this is a fragile approach. It leaves you wondering whether the navigation bar organization will change in the future.


Need Your Help

WPF VisualTreeHelper.HitTest using multiple threads

c# multithreading raycasting inkcanvas viewport3d

In my application, there is a transparent InkCanvas on top of a Viewport3D object. The Viewport3D shows a large 3D mesh. The user will sketch on the InkCanvas in order to select a portion of the 3D...

Building ffmpeg for Windows with MSYS and MinGW

windows-xp ffmpeg mingw

I am trying to build ffmpeg for windows (Xp - SP2) as given here.