views:

391

answers:

1

I've added a few components to the NavigationBar in an app I'm creating. The height of the bar changes dynamically, like in Safari for the iPhone, when you click on the URL field. I have all of the interactions and resizings working perfectly, except when I move to another tab and return.

If I start the app, click on second tab the navbar displays correctly.

navbar OK

If I then immediately click on the first tab, and then back to the second tab again, the NavigationBar is clipped.

navbar clipped

I'm customizing the navbar in my viewWillAppear method

- (void)viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];

    if (navBar == nil) {

        CGFloat width = self.view.frame.size.width;


        navBar = [self.navigationController.navigationBar autorelease];
        navBar.frame = CGRectMake(0,20,width,52);
        //This doesn't appear to have any effect- was set to           
        //UIViewAutoresizingFlexibleWidth and worked but with with the same issue.
        navBar.autoresizingMask = UIViewAutoresizingFlexibleHeight;

        self.navigationItem.title = nil;


        label = [[UILabel alloc] initWithFrame:
             CGRectMake(10,2,width-20,14)];     
        label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        label.text = @"My Custom NavBar";
        label.backgroundColor = [UIColor clearColor];
        label.font = [UIFont systemFontOfSize:12];
        label.textAlignment = UITextAlignmentCenter;
        [navBar addSubview:label];

        urlTextField = [[UITextField alloc] initWithFrame:
                    CGRectMake(10,19,width-75,26)]; 
        urlTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
        [urlTextField addTarget:(id)self action:@selector(textFieldDidChange:) 
                                        forControlEvents:UIControlEventEditingChanged];


        bookmarkButton = [UIButton buttonWithType:UIButtonTypeCustom];
        bookmarkButton.frame = CGRectMake(0,0,21,21);
        [bookmarkButton setImage:[UIImage imageNamed:@"bookmark.png"] forState:UIControlStateNormal];
        [bookmarkButton addTarget:self action:@selector(bookmarkPressed:) forControlEvents:UIControlEventTouchUpInside];
        urlTextField.leftView = bookmarkButton;
        urlTextField.leftViewMode = UITextFieldViewModeAlways;


        actionButton = [UIButton buttonWithType:UIButtonTypeCustom];
        actionButton.frame = CGRectMake(0,0,21,21);
        [actionButton setImage:[UIImage imageNamed:@"refresh.png"] forState:UIControlStateNormal];
        [actionButton addTarget:self action:@selector(actionPressed:) forControlEvents:UIControlEventTouchUpInside];
        urlTextField.rightView = actionButton;
        urlTextField.rightViewMode = UITextFieldViewModeAlways;


        urlTextField.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        urlTextField.borderStyle = UITextBorderStyleRoundedRect;
        urlTextField.font = [UIFont systemFontOfSize:17];
        urlTextField.delegate = self;
        [navBar addSubview:urlTextField];


    } else {

        //XXX This does make the navBar display correctly
        //but I don't really want the keyboard visible when returning from another tab
        //[urlTextField  becomeFirstResponder];

    }

}

Note the final comment in the code above- If I force the keyboard to display, or if the user clicks in the UITextField, the NavBar is displayed correctly from therein.

I've tried a lot of things- checking the frames sizes of the View (View 2 in the images), the NavBar, but with no luck. Does any one have any idea what the problem might be? I'll be happy to give further detail.

Thanks.

+1  A: 

Basically you're going about this all the wrong way. You should never have to access the frame of the navigation bar (let alone change it) and you should certainly never add subviews to it directly. From the docs:

Unlike other types of views, you do not add subviews to a navigation bar directly. Instead, you use a navigation item (an instance of the UINavigationItem class) to specify what buttons or custom views you want displayed.

So in the -(id)initWithNibName:bundle: method of your view controller you want:

// Setting this will automatically grow the height of the navigation bar
// to the appropriate height
self.navigationItem.prompt = @"My Custom NavBar";

// Construct urlTextField here ...
self.navigationItem.titleView = urlTextField;

// This is the button with the gears icon
UIBarButtomItem *rightButtonItem = [[UIBarButtomItem alloc] initWithCustomView:view];
self.navigationItem.rightBarButtonItem = rightButtomItem;
[rightButtomItem release];
moshy
And while I initially marked this as my accepted answer, after changing the code so that I no longer change the navigation bar frame, add UIViews directly to navigation bar (only working with Navigation Items, the issue still happens.
Gene M.
Damn, well you could try calling setNeedsLayout on the view in viewWillAppear:, but I really am just guessing.
moshy
It didn't require calling setNeedsLayout. I had left my fix in that I noted above.
Gene M.
My mistake, so I've accepted your answer again. Thanks, and let that be a lesson to others- RTFM before using a code snippet from the web, which is what I did- and added views directly to the navbar and changed its frame as well.
Gene M.