tacos_tacos_tacos
tacos_tacos_tacos

Reputation: 10585

Strange behavior of titleView that does not appear until back button is pressed

In viewDidLoad I have a UINavigationBar with a custom background implemented in the following way:

[self.navigationController.navigationBar insertSubview:[[UIImageView alloc] initWithImage:[UIImage imageNamed:nav_bg_image]] atIndex:100];

On the top of the stack (call it RVC) I have the following complete code:

UIImageView *logoView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:navbar_image_logo]];
[self.navigationController.navigationBar insertSubview:[[UIImageView alloc] initWithImage:[UIImage imageNamed:nav_bg_image]] atIndex:100];
[self.navigationItem setTitleView:logoView];
[logoView release];

This works brilliantly. However, when I push a new VC on the stack and use the same code in viewDidLoad

UIImageView *logoView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:navbar_image_logo]];
[self.navigationController.navigationBar insertSubview:[[UIImageView alloc] initWithImage:[UIImage imageNamed:nav_bg_image]] atIndex:1];
[self.navigationItem setTitleView:logoView];
[logoView release];
UIBarButtonItem *hButton = [[UIBarButtonItem alloc] initWithTitle:@"Filters" style:UIBarButtonItemStylePlain target:self action:@selector(filtersAction)];
self.navigationItem.rightBarButtonItem = hButton;
[hButton release];

Neither the "Filters" button nor the titleView imageView appears. However, I know the filters button has been added to the UI because if I click in the area that it is supposed to appear, the action is performed.

Furthermore, when I drill down to a detail view DVC and go back, all of the sudden the titleView (logoView) appears!

I suspect that this is some sort of memory issue but I have not been able to resolve it.

Upvotes: 0

Views: 303

Answers (2)

Paul.s
Paul.s

Reputation: 38728

There is a mention of the issue you are having with ordering at iDev Recipes How do iPhone apps Instagram/Reeder/DailyBooth implement custom NavigationBars with variable width back buttons?

Basically you are adding your background in the wrong way.

Support only iOS 5
Implement a method like setBackgroundImage:forBarMetrics:

Support Older iOS's + iOS 5

  1. Subclass UINavigationBar and implement the drawRect

    //.h
    @interface CustomNavigationBar : UINavigationBar
    @end
    
    //.m
    @implementation CustomNavigationBar
    
    - (void)drawRect:(CGRect)rect;
    {
        UIImage *image = [[UIImage imageNamed: @"BackgroundImage"] stretchableImageWithLeftCapWidth:0 topCapHeight:0];
        [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    }
    
    @end
    
  2. To get a UINavigationController to use your subclass you need to create it using a xib.

enter image description here


If you have set everything up in code then you will still need to use a nib to do this. The nib I use has no File's Owner and only contains a Navigation Controller that is configured to use my CustomNavigationBar and has no viewControllers

In this case I set this up in code like this:

// Load my nib with only a Navigation Controller and custom navigationBar
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomNavigationController" owner:nil options:nil];

// The only top level object will be my navigationController
UINavigationController *navigationController = [topLevelObjects objectAtIndex:0];

// Push a view controller to be the rootViewController
[navigationController pushViewController:rootViewController animated:NO];

Then present this controller however I normally would. The controller/window that presents it will take the required retain on the UINavigationController

Upvotes: 2

jstevenco
jstevenco

Reputation: 2953

Your use of the method insertSubView:atIndex: looks suspicious. Do you really have 100 subviews in that view?

Upvotes: 1

Related Questions