iPad custom size of modal view controller

Viewed 67437

I have a couple of modal view controllers of certain size. I'm trying to avoid the use of custom views (creating full screen black translucent overlay over current view, add the modal view over that view, do the animations, etc) to present it because there is no modalPresentationStyle that fits the size of my controllers.

Now I'm using UIModalPresentationPageSheet but my view is smaller in height and I have an ugly blank space

Desired presentation

 _______________
|    _______    |
|   |       |   |
|   |  MyVC |   |
|   |       |   |
|    -------    |
 --------------- 

Actual presentation

 _______________
|   |       |   |
|   |  MyVC |   |
|   |       |   |
|   |-------|   |
|   | blank |   |
 ---------------    

If I use the UIModalPresentationFormSheet the container is smaller in width.

I'm trying to figure out how to do it but I don't know if it's possible. What is the solution to the problem of presenting a modal VC smaller than any of the presentationStyles? The only solution is to arrange a "custom modal view controller engine"? Popovers doesn't fit my design requirements :(

13 Answers

The best way to do this is to change the bounds property on the superview of the view being presented inside the formsheet. When you present a view modally, the presented view is embedded inside another view.

You should set the bounds property of the superview to the same rect as the view's bounds. First add a private ivar in your class:

@implementation MySpecialFormsheet {
    CGRect _realBounds;
} 

It's best to do this in viewWillAppear:. Add the following code to the view controller that is being presented modally:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.view.superview.bounds = _realBounds;
}

You need to cache _realBounds in your viewDidLoad method:

- (void)viewDidLoad {
    _realBounds = self.view.bounds;
    [super viewDidLoad];
}

The approaches described above need to be tweaked for iOS7:

// set desired bounds, then call -presentFromViewController:

@implementation PresentedViewController
{
    CGRect _presentationBounds;
}

- (void)presentFromViewController:(UIViewController *)viewController
{
    self.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    self.modalPresentationStyle = UIModalPresentationFormSheet;

    _presentationBounds = self.view.bounds;

    [viewController presentViewController:self animated:YES completion:nil];
}

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    if (!CGRectIsEmpty(_presentationBounds))
    {
        self.view.superview.bounds = _presentationBounds;
        _presentationBounds = CGRectZero;
    }
}

(This code also works on iOS6.)

One solution is to use UIModalPresentationPageSheet to present a page sheet and then immediately resize the modal view. This is fully explained in this answer to another question.

Related