Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Present View Controller Within Popup

So I have my main view controller. That view controller has a bar button item with a storyboard segue with kind set as Present As Popover.

This all works as expected. But when you tap another button within that popover view controller it presents the view full screen. I want it to display within the popover. Like push/display on top of the existing popover bounds.

How can I achieve this?

I only want this behavior on iPad. But I think it does that by default.

Edit

I'd prefer to do this all in the storyboard but am willing to do it with Swift code as well if that is what's required.

like image 928
Charlie Fish Avatar asked May 14 '17 23:05

Charlie Fish


2 Answers

Create a IBAction of your UIBarButtonItem, and in action:

- (IBAction)popupAction:(UIBarButtonItem *)sender {
    UIViewController *vc = [[UIViewController alloc] init];  // I don't use segue
    vc.view.backgroundColor = [UIColor grayColor];
    vc.modalPresentationStyle = UIModalPresentationPopover;
    UIPopoverPresentationController *popvc = vc.popoverPresentationController;
    popvc.delegate = self;
    popvc.permittedArrowDirections = UIPopoverArrowDirectionAny;
    popvc.barButtonItem = sender; // if UIBarButtonItem
    // if view
    // popvc.sourceView = sender;
    // popvc.sourceRect = sender.bounds;

    vc.preferredContentSize = CGSizeMake(200, 200);

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

And the UIPopoverPresentationControllerDelegate:

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection{
    return UIModalPresentationNone;
}

- (BOOL)popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController{
    return YES;
}

Swift:

@IBAction func popupAction(_ sender: UIBarButtonItem) {
    let vc = UIViewController.init()
    vc.view.backgroundColor = UIColor.gray
    vc.modalPresentationStyle = UIModalPresentationStyle.popover
    let popvc = vc.popoverPresentationController
    popvc?.delegate = self
    popvc?.permittedArrowDirections = UIPopoverArrowDirection.any
    popvc?.barButtonItem = sender
    vc.preferredContentSize = CGSize.init(width: 200, height: 200)

    self.present(vc, animated: true, completion: nil)
}

func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
    return UIModalPresentationStyle.none
}

func popoverPresentationControllerShouldDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) -> Bool {
    return true
}

This works on both iPad and iPhone.

Result:

Popover another viewController in a popover controller:

like image 177
tomfriwel Avatar answered Nov 07 '22 10:11

tomfriwel


This is only with Storyboard.

1) Create an UIViewController (blue) and ctrl + drag (mouse) from your UIBarButtonItem to the UIViewController and select "present as Popover" (like you did).

2) Click on the UIViewController (blue) and click on Editor->embed in->Navigation Controller (this will be trick to let the next controller stay in the popup)

3) Create a second UIViewController (green)

4) Create a UIButton in the first UIViewController (blue) and ctrl + drag from the button to the second UIViewController (green) and select "show"

At the end it should look like this in Storyboard:

enter image description here

And the result:

enter image description here

enter image description here

If you want the PopOver without the navigationBar you can use in the blue controller:

self.navigationController?.isNavigationBarHidden = true

and to go back from the green to the blue view you can use in the green controller:

@IBAction func backToBlueController(sender: UIButton) {
        self.navigationController?.popViewController(animated: true)
}

Additional:

If you don't want to use the popUp you could also change the segue kind from the barButtonItem to the navigationController to

Present Modally

and the presentation to something like

Form Sheet

in Storyboard.

enter image description here

At a glance, you should always use an UINavigationController to manage your navigation, even if you don't need the navigationBar, because the navigation controller provides you a navigation stack from where you can pop and push into it.

UINavigationController Reference

like image 5
Retterdesdialogs Avatar answered Nov 07 '22 08:11

Retterdesdialogs