Custom size for Modal View loaded with Form Sheet presentation
Asked Answered
N

10

53

I'm trying to load a UIViewController in iPad with Form Sheet presentation. The problem is the size of this new view, i put the size values in the IBuilder but the modal view take a fixed value.

Also i tried to make this in prepareForSegue like this:

HelpViewController *viewController = segue.destinationViewController;
viewController.view.superview.frame = CGRectMake(0, 0, 200, 200);

But don't work, any help? Thanks!

Nest answered 13/5, 2013 at 8:56 Comment(3)
Hi, i got set a custom size in viewWillAppear method of the modal view using: [self.view.superview setBounds:CGRectMake(0, 0, 200, 200)]; But now, the window is not centered with the layoutNest
read thisVenation
#25788446 Check this link you can get the solutionAllanson
A
86

For iOS 8, use:

self.preferredContentSize = CGSizeMake(width, height);

I've placed this in viewDidLoad.

Swift 3

self.preferredContentSize = CGSize(width: 100, height: 100)
Altis answered 10/9, 2014 at 13:58 Comment(7)
How do you set this in Interface Builder?Korenblat
in IOS 8 migration, how can i change the position?Ingesta
preferredContentSize is introduced in iOS 7Menorah
Works for iOS9+ alsoTragopan
For this to work, I had to use .modalPresentationStyle = .formSheetLintwhite
It's not working for me. After presenting the xib as formsheet, I am changing the content size after some user inputs. It's not getting changed, but if I rotate the screen it's reflecting. Xcode 10 and iOS 12.1Kalasky
Worked for me (iOS 13), using .modalPresentationStyle = .formSheet and view controller in storyboard with size FreeformEndaendall
K
23

In Attributes inspector check Use Preferred Explicit Size

enter image description here

Kacikacie answered 13/7, 2016 at 13:6 Comment(2)
This is working if you set the Presentation to Form Sheet.Jerol
How can I decrease the transparency black when presenting as form sheet?Cypro
D
15

Setting preferredContentSize didn't work for me on iOS 11 for example when presenting EKEventEditViewController.

It works only if I override getter of preferredContentSize. Something like this:

private class CLEventEditViewController: EKEventEditViewController {
    override var preferredContentSize: CGSize {
        get {
            if let fullSize = self.presentingViewController?.view.bounds.size {
                return CGSize(width: fullSize.width * 0.5,
                              height: fullSize.height * 0.75)
            }
            return super.preferredContentSize
        }
        set {
            super.preferredContentSize = newValue
        }
    }
}

enter image description here enter image description here

Daladier answered 5/10, 2017 at 20:29 Comment(1)
Eliminate your optional by using let fullSize = super.preferredContentSizeFugleman
W
11

EDIT

Use preferredContentSize.

Old

You can try this for show view in center

HelpViewController * viewController = [[[HelpViewController alloc] init] autorelease];
viewController.modalPresentationStyle=UIModalPresentationFormSheet;
viewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:viewController animated:YES completion:^{
    viewController.view.superview.frame = CGRectMake(0, 0, 200, 200);
    viewController.view.superview.center = self.view.center;
}];
Wendt answered 14/8, 2013 at 6:57 Comment(2)
At least in iOS 7 this doesn't work - it shows it presenting if full size, and then afterwards it shrinks it. As evidenced by the 'completion' block.Secant
To perform this on iOS7 take a look on this https://mcmap.net/q/340427/-popover-with-modalpresentationstyle-is-not-centered-in-ios-7-ipadBarger
B
3

My solution is based heavily on other solutions posted here but since I had to try many different things to get it to actually work I am posting it. Mine is for iOS 10 with Swift 3.1 in a portrait-mode only app. (Untested in landscape mode) The goal of my solution was to display a modal that was smaller than the presenting view, and such that I could see the presenting view in the background.

I had to configure the UIViewController properly in Interface Builder or my code wouldn't work. Here are my settings. I found my solution to work with both Cross Dissolve and Cover Vertical transition styles. I think the key for me in IB was the Over Full Screen for Presentation - it didn't appear to work with some other values for this setting.

IB Settings

Here is the code in the UIViewController I want to present modally. Then I just call it using present(_:animated:completion:) elsewhere. Also, in the VC I will present modally, I have a bool, didLayout initialized as false:

override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        if !didLayout {

            let width:CGFloat = self.view.bounds.width * 0.95 //modify this constant to change the amount of the screen occupied by the modal
            let height:CGFloat = width * 1.618 //golden ratio

            self.view.superview!.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.15) //slightly dim the background to focus on the modal
            let screen = self.view.superview!.bounds
            let frame = CGRect(x: 0, y: 0, width: width, height: height)
            let x = (screen.size.width - frame.size.width) * 0.5
            let y = (screen.size.height - frame.size.height) * 0.5
            let mainFrame = CGRect(x: x, y: y, width: frame.size.width, height: frame.size.height)

            self.view.frame = mainFrame

            didLayout = true
        }
    }
Bullen answered 27/6, 2017 at 17:55 Comment(1)
It's important to note that Over Full Screen is a different presentation style than Form Sheet, so even if your answer may actually help people who are better served using Over Full Screen , the question is specifically addressing the latter. For a list of all the modal presentation style options, see: developer.apple.com/documentation/uikit/…Ebro
E
2

I solved it like @Stuart Campbell and @Viruss mca.

Edited

After @Erich's comment, I rewrote it to run in iOS 8 too. Below is the code:

  HelpViewController * viewController = [[[HelpViewController alloc] init]];
  viewController.modalPresentationStyle=UIModalPresentationFormSheet;
  [self presentViewController:viewController animated:YES completion:nil];

--

//HelpViewController.m

- (void) viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    if (!didLayout) {
        [self layout];
        didLayout = YES;
    }
}
- (void) layout{
    self.view.superview.backgroundColor = [UIColor clearColor];
    CGRect screen = self.view.superview.bounds;
    CGRect frame = CGRectMake(0, 0, <width>, <height>);
    float x = (screen.size.width - frame.size.width)*.5f;
    float y = (screen.size.height - frame.size.height)*.5f;
    frame = CGRectMake(x, y, frame.size.width, frame.size.height);

    self.view.frame = frame;
}
Electricity answered 8/8, 2014 at 20:4 Comment(1)
Creating problem in orientation changesIngesta
T
2

If you are using a view in XIB that is set as a modally presented view for a view controller. A very easy way to fix this is to simply change the Size Metrics to Freeform (See Figure 1.0) and resize the view to whatever you want it to be. The view will appear with these metrics when loaded modaly.

Setting Preferred Content Size didn't help in my case but this fixed my issue. It

Figure 1.0:

enter image description here

Topgallant answered 11/7, 2019 at 7:34 Comment(0)
H
1

I got around this problem by putting my content inside a view in the modal vc. Then setting the vc background transparent and in viewWillAppear settings the formsheet background transparent. This means you only see the content.

// In Modal vc
- (void)viewWillAppear:(BOOL)animated
{
    self.view.superview.backgroundColor = [UIColor clearColor];
    [super viewWillAppear:animated];
}

I set it all from storyboard and used a segue, if using code you would need to set this also.

parentViewController.modalPresentationStyle = UIModalPresentationPageSheet;
Hedvah answered 18/12, 2013 at 11:14 Comment(0)
A
1

Erich's post worked for me, but on iOS 10 with Swift 3, I had to use:

self.preferredContentSize = CGSize(width, height)

I too placed it in viewdidload

Also, like avdyushin said, I had to check the Use Preferred Explicit Size box.

Abridgment answered 15/1, 2017 at 14:10 Comment(0)
S
0

I also had this issue, You should resize superview's frame after presenting it.

HelpViewController *viewController = segue.destinationViewController;
viewController.modalPresentationStyle = UIModalPresentationPageSheet;
[self presentViewController:viewController animated:YES completion:nil];
viewController.view.superview.frame = CGRectMake(0, 0, 200, 200);
Stalk answered 14/8, 2013 at 6:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.