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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With