InsertWittyName InsertWittyName - 2 months ago 21
iOS Question

UINavigationItem Prompt Issue

I'm having a problem with the prompt on a UINavigationItem that I just can't resolve...

I have a master and a detail view controller. When I push from the master to the detail a prompt is shown on the detail view controller:

prompt

However, when I pop back to the master view controller, the view isn't resized and the window shows through (the window has been coloured red):

window

This only happens on iOS7, on iOS6 the view resizes as expected.

I've tried a few things such as setting the prompt to nil in

viewWillDisappear
or
viewDidDisappear
but nothing seems to fix it.

If I set the navigation bar in the navigation controller to translucent it does fix this - unfortunately that's not an option.

I've created a very small example project here which demonstrates the issue: https://github.com/InsertWittyName/NavigationItemPrompt

Thanks in advance for any help!

Answer

A solution I can think of is to subclass the UIView of the master, and implement viewDidMoveToSuperview to set the frame of the view to be from the navigation bar's height to the end of the superview. Since the navigation bar is not translucent, your job is easier, as you don't have to take into account layout guides and content insets.

A few things to notice. When pushing and popping, the system moves your view controller's view into another superview for the animation and then returns it to the navigation controller's private view hierarchy. Also, when a view goes outside of the view hierarchy, the superview becomes nil.

Here is an example implementation:

@interface LNView : UIView

@end

@implementation LNView

- (void)viewDidMoveToSuperview
{
    [super viewDidMoveToSuperview];

    if(self.superview != nil)
    {
        CGRect rect = self.superview.bounds;

        rect.origin.y += 44;
        rect.size.height -= 44;

        [self setFrame:rect];
    }
}

@end

This is not a perfect implementation because it uses a hardcoded value for the navigation bar's height, does not take into account a possible toolbar, etc. But all these you can add as properties to this view and in viewDidLoad, before it starts going into the view hierarchy, set the parameters according to your needs.