Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPad/iOS7: 'Page' modal view controller strange behaviour after presenting 'Full screen' view controller from it

Tags:

ios

ios7

ipad

My iPad application opens modal view controller with 'Page' presentation style. As you know 'Page' presentation style doesn't cover status bar of presenting view controller to indicate page presentation.

Initial view controller

Page modal view controller

From the modal view controller the app opens UIImagePickerController to make photo. UIImagePickerController has 'Full screen' presentation style. After dismissing image picker presenting modal view controller become 20px taller and overlaps status bar of the initial view controller.

I tried to replace UIImagePickerController with simple UINavigationController and it breaks my modal view controller too.

There are screen shots: Full screen view controller

Broken modal view controller

They only way to restore size of 'Page' view controller is changing height of viewController.view.superview.superview.superview.superview frame after returning to 'Page' view controller. But it's really weird.

Is there another way to fix 'Page' modal view controller presentation after dismissing nested modal view controller?

UPDATE: I used such weird code to solve my problem:

#define STATUS_BAR_HEIGHT 20
#define IPAD_PORTRAIT_HEIGHT 1004
#define IPAD_LANDSCAPE_HEIGHT 748
UIView *superview = nil;

// In case of this view controller included in navigationController we have to use superview of navigation's controller view
if (self.navigationController)
    superview = self.navigationController.view.superview;
else
    superview = self.view.superview;

CGRect r = superview.frame;

// Sometimes we have to fix height + origin, sometimes only height (becase view has bottom magnifying)
// In landscape orientation we have to fix 'width' instead of 'height', because that view controller always works in 'portrait' mode
if (self.interfaceOrientation == UIInterfaceOrientationPortrait && r.size.height > IPAD_PORTRAIT_HEIGHT) {
    r.origin.y = STATUS_BAR_HEIGHT;
    r.size.height = IPAD_PORTRAIT_HEIGHT;
}
else if (self.interfaceOrientation == UIInterfaceOrientationMaskPortraitUpsideDown && r.size.height > IPAD_PORTRAIT_HEIGHT) {
    r.size.height = IPAD_PORTRAIT_HEIGHT;
}
else if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft && r.size.width > IPAD_LANDSCAPE_HEIGHT) {
    r.size.width = IPAD_LANDSCAPE_HEIGHT;
    r.origin.x = STATUS_BAR_HEIGHT;
}
else if (self.interfaceOrientation == UIInterfaceOrientationLandscapeRight && r.size.width > IPAD_LANDSCAPE_HEIGHT) {
    r.size.width = IPAD_LANDSCAPE_HEIGHT;
}

superview.frame = r;

I don't believe that there is no more elegant solution. Any ideas how to improve it?

UPDATE2: I've just opened a bug. You can follow it there: rdar://15949644

UPDATE3: There is my sample project: link

like image 331
Vitaly S. Avatar asked Jan 15 '14 19:01

Vitaly S.


2 Answers

There is no good solution, it's an Apple bug, and until it is fixed, you have to work around it. It has not been fixed in iOS 7.1. I worked on a solution to this and realized I was implementing the same solution as well. It's ugly, but it works.

A word on this design. My guess why Apple overlooked this problem is because presenting a view controller in fullscreen is not something Apple would do. This is not an excuse of course, and sometimes there is no other option but to present fullscreen (we had to open a camera view, which must be opened in fullscreen, for example). Perhaps you can change your design to accommodate Apple's bugs.

like image 60
Léo Natan Avatar answered Nov 16 '22 08:11

Léo Natan


"Ensure that the ViewController that is presenting the modal view is in a NavigationController and this weirdness should stop. " My initial answer - wrong

Updated This does indeed sound like a bug, although from a user experience point of view one you shouldn't really hit. It seems a little wrong to present a view controller that is in the 'Page' presentation style and then to present another over it in full screen mode.

IMO that's just bad design from the outset so the fact that it doesn't act as you'd expect probably is because whoever set it up didn't anticipate someone using it like that.

I would, pretty much as my initial answer stated albeit briefly, embed your modally presented view controller in a navigation controller and push the UIImagPickerViewController in to that or add it's view animated to yours as if it then appears to be presented like another page styled modal view. If that's you desired affect.

None of that sounds perfect, a more perfect solution would be to look at the flow of you app and perhaps reevaluate how things are presented.

like image 34
AppHandwerker Avatar answered Nov 16 '22 09:11

AppHandwerker