简体   繁体   中英

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.

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:

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:

在此输入图像描述

And the result:

在此输入图像描述

在此输入图像描述

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.

在此输入图像描述

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

Have you tried it - EzPopup ( https://github.com/huynguyencong/EzPopup ), a Swift pod. Just a few lines of code:

// init YourViewController
let contentVC = ...

// Init popup view controller with content is your content view controller
let popupVC = PopupViewController(contentController: contentVC, popupWidth: 100, popupHeight: 200)

// show it by call present(_ , animated:) method from a current UIViewController
present(popupVC, animated: true)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM