4

I am using the iOS7 custom transitions to modally present a new view controller.

The new view controller is a navigation controller.

The controller animates up from the bottom, while the background view blurs.

My issue is that the navigation bar on the new controller, while animating upwards, appears to allows for a status bar, ie it seems to be 64 points high. When it has reached its final location and called completeTransition it realises no status bar space is required and snaps back to 44 points.

Is there a way to

  • Initially inform the nav controller/top view controller that no status bar is required. OR
  • Call whatever method that completeTransition is calling before the animation so that the automatic re-adjusting takes place then.

While animating:

While animating

Animation complete:

Animation complete

Alan
  • 4,325
  • 3
  • 21
  • 25

3 Answers3

7

The trick was to add the view of the presented view controller to the container view AFTER setting its initial position off the bottom of the screen. This prevents the container view from thinking it is at the top of the screen and automatically laying out with status bar provision accordingly.

It is related to the following from WRESTLING WITH STATUS BARS AND NAVIGATION BARS ON IOS 7:

"UINavigationController will alter the height of its UINavigationBar to either 44 points or 64 points, depending on a rather strange and undocumented set of constraints. If the UINavigationController detects that the top of its view’s frame is visually contiguous with its UIWindow’s top, then it draws its navigation bar with a height of 64 points. If its view’s top is not contiguous with the UIWindow’s top (even if off by only one point), then it draws its navigation bar in the “traditional” way with a height of 44 points. This logic is performed by UINavigationController even if it is several children down inside the view controller hierarchy of your application. There is no way to prevent this behavior."

Alan
  • 4,325
  • 3
  • 21
  • 25
0

Alan, since you haven't marked your question answered I'm putting this up so others can find it. I ran into a similar situation and your fix wouldn't work in my case so this more general solution may be more widely helpful.

Found over here Navigation bar has wrong position when modal a view controller with flip horizontal transition in iOS 7

A quick workaround is to put:

[self.navigationController.navigationBar.layer removeAllAnimations];    

In the viewWillAppear of the view you are transitioning to. This would avoid the need to first place your view below the screen and then move it up before animating.

As you pointed out above, the UINavigationController is figuring out it's size at some point and this is conflicting with the animation.

Community
  • 1
  • 1
DC2
  • 119
  • 8
0

I had similar problems with the UINavigationBar.

In one case, it was in a custom splitview (we can't use the UIKit one because there are some features missing in iOS 5.0) and also with a UINavigationController that has its view added inside another view.

The use of controller hierarchy helped a lot here, it seems iOS also pays some attention to that when deciding how to layout the UINavigationBar. I was able to have a UINavigationController with the correct height defined by the OS without having the UINavigationBar contiguous with its UIWindow’s top, so that is possible to do.

There was a problem however, when the view first appeared it had the incorrect height and then kind of automatically increased to have the correct height of 64 pixels all by itself.

The solution to get the view with the correct height from the start was to initially define the view with the whole width of the screen and then use the [UIViewController viewDidLayoutSubviews] method to define the frame of the view with the width I wanted.

This meant the controller was doing the layout of the UINavigationBar the way I wanted it to and then I would correct the frame of the view and that would not change the height of the UINavigationBar.

For the specific situation the OP presented, you can do the contrary. First define the view with half the width so the bar is small at the beginning and then change the width back to what you want. I tested this in another situation and it also worked, but it didn't had an animation, that may kill my solution. I recommend changing the width and the x position.

This is a terrible hack, so if someone comes up with a solution that will allow me to remove this code, do share.