Incorrect frame when dismissing modally presented view controller Incorrect frame when dismissing modally presented view controller objective-c objective-c

Incorrect frame when dismissing modally presented view controller


I tried both wrapper approaches mentioned. One side effect of using this wrapping approach is that device rotation doesn't display well - introducing black boxes around the presented view.

Instead of doing the wrapping trick, try setting the modalPresentationStyle of the presented UIImagePickerController to UIModalPresentationOverFullScreen. This means the views underneath the image picker won't be removed/restored from the view hierarchy during presentation/dismissal.


This is expected because the fullscreen presentation does not restore the original frame computed by frameOfPresentedViewInContainerView.The recommended way to fix this is to create a wrapper view in which you will insert the presented view controller's view. Here is the relevant code for your custom presentation controller:

- (void)presentationTransitionWillBegin {    // wrapper is a property defined in the custom presentation controller.    self.wrapper = [UIView new];    [self.wrapper addSubview:self.presentedViewController.view];}- (CGRect)frameOfPresentedViewInContainerView {    CGRect result = self.containerView.frame;    // In this example we are doing a half-modal presentation    CGFloat height = result.size.height/2;    result.origin.y = height;    result.size.height = height;    return result;}- (UIView *)presentedView {    return self.wrapper;}- (BOOL)shouldPresentInFullscreen {    return NO;}- (void)containerViewWillLayoutSubviews {    self.wrapper.frame = self.containerView.frame;    self.presentedViewController.view.frame = [self frameOfPresentedViewInContainerView];}

Note that we override presentedView to return the wrapper view instead of the default value – the presented view controller's view. This way, even if the second presentation modifies the wrapper's frame the presented view controller's view will not change.


erudel's solution didn't work for me as is, but adding another view in between wrapperView and presentedViewController.view did the trick (I have no idea why):

- (instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController                       presentingViewController:(UIViewController *)presentingViewController {    if (self = [super initWithPresentedViewController:presentedViewController                             presentingViewController:presentingViewController]) {        _wrapperView = [[UIView alloc] init];        _wrapperView2 = [[UIView alloc] init]; // <- new view    }    return self;}- (CGRect)frameOfPresentedViewInContainerView {    return self.containerView.bounds;}- (UIView *)presentedView {    return self.wrapperView;}- (BOOL)shouldPresentInFullscreen {    return NO;}- (void)containerViewWillLayoutSubviews {    self.wrapperView.frame = self.containerView.frame;    self.wrapperView2.frame = /* your custom frame goes here */;    self.presentedViewController.view.frame = self.wrapperView2.bounds;}- (void)presentationTransitionWillBegin {    [self.wrapperView addSubview:self.wrapperView2];    [self.wrapperView2 addSubview:self.presentedViewController.view];    // Set up a dimming view, etc}

Tested this on iOS 9.3.