Previous 1 2 Next 27 Replies Latest reply: Feb 20, 2010 9:14 PM by GregM
hubermat Level 1 Level 1 (20 points)
Hi,
how to set a custom background image for the whole navigation bar of a navigation controller? I can't find any appropriate API method.
I tried already to mess around with the views of the UINavigationBar to insert my background view - with the result no not-showing buttons and titles :-/
Also subclassing of UINavigationBar with a new drawRect method does not lead to anywhere - there is simply now way to set the navigation bar for a UINavigationController!
Any help would be highly appreciated!
Best regards,
Matthias Huber

MacBook, Mac OS X (10.5.4), iPhone OS 2.0
  • mlara Level 1 Level 1 (5 points)
    Create a category that extends UINavigationBar:

    @implementation UINavigationBar (UINavigationBarCategory)
    -(void)setBackgroundImage:(UIImage*)image{
    if(image == NULL){ //might be called with NULL argument
    return;
    }
    UIImageView *aTabBarBackground = [[UIImageView alloc]initWithImage:image];
    aTabBarBackground.frame = CGRectMake(0,0,self.frame.size.width,self.frame.size.height);
    [self addSubview:aTabBarBackground];
    [self sendSubviewToBack:aTabBarBackground];
    [aTabBarBackground release];
    }
    @end


    And call this method from wherever you are initializing your UINavigationController:


    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
    // Initialization code

    // Create the navigation and view controllers
    SinglePlayerRootViewController *_rootViewController = [[SinglePlayerRootViewController alloc] initWithStyle:UITableViewStyleGrouped];
    UINavigationController *_navigationController = [[UINavigationController alloc] initWithRootViewController:_rootViewController];
    self.navigationController = _navigationController;
    [_navigationController release];
    [_rootViewController release];

    // set the image for the top navigation bar
    [[navigationController navigationBar] setBackgroundImage:[UIImage imageNamed:@"NavigationBarBackgroundTop.png"]];

    // Configure and show the window
    [self.view addSubview:navigationController.view];
    }
    return self;
    }


    I hope this helps!
    -ML
  • JeyB Level 1 Level 1 (0 points)
    I was doing this a similar way and your method appears to have the same flaw. This works for the first screen of the navigation controller but as soon as you go to a new view controller the title then appears behind the image that's been set as background. I guess the navigation controller must add the new navigation item at index 0 which is where the background image is.

    I've not found a way around this yet, but there are apps out there doing it so... help!
  • eknathkadam Level 1 Level 1 (10 points)
    I am struggling with same issue. Have you found a good solution for this?
  • dpedley Level 1 Level 1 (0 points)
    Not sure if this addition is what you were hoping for, but I'm using this:

    /* input: The image and a tag to later identify the view */
    @implementation UINavigationBar (UINavigationBarCategory)
    -(void)setBackgroundImage:(UIImage*)image withTag:(NSInteger)bgTag{
    if(image == NULL){ //might be called with NULL argument
    return;
    }
    UIImageView *aTabBarBackground = [[UIImageView alloc]initWithImage:image];
    aTabBarBackground.frame = CGRectMake(0,0,self.frame.size.width,self.frame.size.height);
    aTabBarBackground.tag = bgTag;
    [self addSubview:aTabBarBackground];
    [self sendSubviewToBack:aTabBarBackground];
    [aTabBarBackground release];
    }
    /* input: The tag you chose to identify the view */
    -(void)resetBackground:(NSInteger)bgTag {
    [self sendSubviewToBack:[self viewWithTag:bgTag]];
    }
    @end

    You will probably do well with the resetBackground called in each viewcontroller's viewDidAppear like so:

    - (void)viewDidAppear:(BOOL)animated
    {
    [super viewDidAppear:animated];
    [[self.navigationController navigationBar] resetBackground:8765309];
    }


    The 8765309 is the tag number for this example, it can be anything you like.
    It must be the same number you use when setting the background tag.

    [[self.navigationController navigationBar] setBackgroundImage:myBackgroundImage withTag:8675309];
  • nicotine Level 1 Level 1 (0 points)
    For some reason this hides the right hand UIBarButtonItem if there is one
  • Branded3 Level 1 Level 1 (0 points)
    This looks like it will solve my problems too, but Im a little confused how to implement it.

    Do I create a new class called UINavigationItem?

    Also what is UINavigationBarCategory?
  • Branded3 Level 1 Level 1 (0 points)
    So I figured it out, so here's some info for the rest of you newbs.

    I put the following piece of code in my AppDelegate.m file above my @implementation AppDelegate line (still dont know what UINavigationBarCategory is for)

    /* input: The image and a tag to later identify the view */
    @implementation UINavigationBar (UINavigationBarCategory)
    -(void)setBackgroundImage:(UIImage*)image withTag:(NSInteger)bgTag{
    if(image == NULL){ //might be called with NULL argument
    return;
    }
    UIImageView *aTabBarBackground = [[UIImageView alloc]initWithImage:image];
    aTabBarBackground.frame = CGRectMake(0,0,self.frame.size.width,self.frame.size.height);
    aTabBarBackground.tag = bgTag;
    [self addSubview:aTabBarBackground];
    [self sendSubviewToBack:aTabBarBackground];
    [aTabBarBackground release];
    }
    /* input: The tag you chose to identify the view */
    -(void)resetBackground:(NSInteger)bgTag {
    [self sendSubviewToBack:[self viewWithTag:bgTag]];
    }
    @end

    Then placed the following code in my applicationDidFinishLaunching

    RootViewController *_rootViewController = [[RootViewController alloc] init];
    UINavigationController *_navigationController = [[UINavigationController alloc] initWithRootViewController:_rootViewController];
    _navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
    self.navigationController = _navigationController;
    [_navigationController release];
    [_rootViewController release];
  • Branded3 Level 1 Level 1 (0 points)
    I have found that this looses the text title that may have been in place, does anyone know how to get this back, or what the best way is, without having to add a new sub vew
  • Vayu4 Level 1 Level 1 (0 points)
    The title remains ther either it is behind the image or u may not see it if ur image color matches the title..I think u can push the title to left or right by adding a leftbaritem or rightbar item
  • LucasTizma199 Level 1 Level 1 (0 points)
    (still dont know what UINavigationBarCategory is for)

    Categories are typically used to extend or partially override the functionality of existing classes without needing to a) subclass them or b) replace the classes with an entire different, custom class.

    So someone else could create a MyAWESOMEUINavigationBarCategory (naming conventions notwithstanding) and include it in their project to achieve an entirely different set of functionality without having to change their code at all. It's really slick.
  • LucasTizma199 Level 1 Level 1 (0 points)
    Thanks for mentioning the need to reset the background image's view "depth." I was missing this key aspect of this solution.
  • Collin Allen Level 1 Level 1 (5 points)
    Try overriding - (void)drawRect:(CGRect)rect like so:

    @implementation UINavigationBar (CustomImage)
    - (void)drawRect:(CGRect)rect {
    UIImage *image = [UIImage imageNamed: @"NavigationBar.png"];
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    }
    @end


    This works well for me, and doesn't appear to have issues with pushing new view controllers, hidden titles and bar button items, etc. I'm still fairly new at this, though
  • LucasTizma199 Level 1 Level 1 (0 points)
    Thank you! This is EXACTLY what I needed to do. Rather than mess with setting images and switching them back and forth, I completely forgot about drawRect. Now I can just set left, title, and right views for my UINavigationItem to achieve completely custom styling.
  • Finger Tappin Level 1 Level 1 (0 points)
    Tremendous. Thanks for this. Short, simple, works.

    Cheers!

    Jeff
Previous 1 2 Next