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, ad
I obtained the following result (link text) by using:
self.modalPresentationStyle = UIModalPresentationFormSheet;
and by presenting it as a modal view controller. Let me know if you need further help.
This is my solution for a NOT autolayout view (never tried with autolayout) and compliant with iOS 7 and iOS 8.
At first be sure to call the modal view in this way:
CloudSettingsViewController *cloudController = [[CloudSettingsViewController alloc] initWithNibName:@"CloudSettingsView" bundle:nil];
CGRect originalBounds = cloudController.view.bounds;
cloudController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
cloudController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:cloudController animated:YES completion:nil];
With iOS 8 set the preferredContentSize in the viewDidLoad method of the modal view.
- (void)viewDidLoad {
[super viewDidLoad];
// backup of the original size (selected in interface builder)
height = self.view.frame.size.height;
width = self.view.frame.size.width;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) // versioni successive ios 8
self.preferredContentSize = CGSizeMake(width, height); // this is necessary to get the correct size of the modal view
}
This works ALSO when the modal view needs to display the keyboard on iPad.
With previous versions of iOS 8 you should set the bounds after presentViewController call:
[currentController presentViewController:controlPanelController animated:YES completion:nil];
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8)
cloudController.view.superview.bounds = originalBounds;//it's important to do this after
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.
This solution worked for me as I had the same issue.
My modal view structure is the following (I use UIModalPresentationCurrentContext at both presenting and presented controllers to achieve transparency in the presented VC)
ModalViewController
> UIView (view) - resized to the same size as the presenting controller but has semi-translucent background - done automatically
>> UIView (contentView) - the true view with the content of the popup - this is the one that got consistently placed at the top of the screen all the time
In ModalViewController I overwrote the following method to fix the positioning issue:
- (void) viewWillLayoutSubviews(){
[super viewWillLayoutSubviews];
CGRect r = self.view.bounds();
self.contentView.center = CGPointMake(r.size.width/2,r.size.height/2);
}
I actually create and size the content view first but in different method.
Hope this helps someone.
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.)
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];
}