UIModalPresentationPopover for iPhone 6 Plus in landscape doesn't display popover
Asked Answered
O

4

35

I want to always present a ViewController in a popover on all devices and all orientations. I tried to accomplish this by adopting the UIPopoverPresentationControllerDelegate and setting the sourceView and sourceRect.

This works very well for all devices and orientations, except the iPhone 6 Plus in landscape. In that case the view controller slides up from the bottom of the screen in a form sheet. How can I prevent that so that it will always appear in a popover?

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let popoverPresentationController = segue.destinationViewController.popoverPresentationController
popoverPresentationController?.delegate = self
popoverPresentationController?.sourceView = self.titleLabel!.superview
popoverPresentationController?.sourceRect = self.titleLabel!.frame }

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.None }

All device are under iOS 8.2 or higher

Organography answered 21/5, 2015 at 15:34 Comment(0)
C
82

Implement the new adaptivePresentationStyleForPresentationController:traitCollection: method of UIAdaptivePresentationControllerDelegate:

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection {
    // This method is called in iOS 8.3 or later regardless of trait collection, in which case use the original presentation style (UIModalPresentationNone signals no adaptation)
    return UIModalPresentationNone;
}

UIModalPresentationNone tells the presentation controller to use the original presentation style which in your case will display a popover.

Counterreply answered 27/5, 2015 at 11:47 Comment(6)
Good call! I forgot that the delegate method changed for 8.3.Risley
@PetahChristian Thanks! Yeah was quite a quiet change and doesn't appear to be documented other than in the API diffs.Counterreply
@Counterreply YES ! I did implement - (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller { return UIModalPresentationNone; } but the new API solve my issue, thank you sir !Organography
For some reason it took me three reads to finally see the :traitCollection part of that delegate method. I initially thought, "yes, I've implemented that" since the shorter version works for the other devices. Thanks! ... I've been beating my head against the wall as to why it wouldn't work for 6+. It's always the simplest things.Advertent
Why did Apple do this specific change for the 6/7 Plus in landscape? Why not just display a popover if that's what you requested?Wiese
Thank you for this! Should I keep the shorter version of this (without the traitColleciton) also implemented if my minimum iOS is 9, or I'm good with just this method?Esquibel
D
7

In Swift 3, if you implemented the original adaptivePresentationStyle method, simply adding this code works:

func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
    return adaptivePresentationStyle(for: controller)
}
Disappointed answered 24/11, 2016 at 20:20 Comment(0)
V
2

A note to people having issues with this:

This

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

Is not the same as this

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

The later will not get called / work the same as the former.

Verbal answered 5/11, 2019 at 16:23 Comment(0)
R
1

Apple designed the iPhone 6 Plus presentation to behave that way, based on its size class.

To prevent the modal presentation on the iPhone 6 Plus, you'll have to override the trait collection (horizontal size).

You should be able to set the overrideTraitCollection property for the presentation controller:

presentedVC.presentationController.overrideTraitCollection = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];

(Sorry for the Objective C! I haven't learned Swift yet.)

Risley answered 22/5, 2015 at 15:57 Comment(4)
I'm sorry but it didn't work for me, I'm not able to override the traitCollection, the "mean to be" popover is still presented as page sheet on iPhone 6 plus landscaped onlyOrganography
While intrigued, I don't have the time this morning to investigate this. I can offer a bounty on the question to draw some attention to it. :)Risley
I saw it, thank you :) The traitCollection override seemed to be a great idea, but it seems to be ignored.Organography
well, it overrides the trait collection when you add this line before you set the modalPresentationStyle = UIModalPresentationPopover but, i think the UIPopoverPresentationController don't know about this change and still showing without the navbar to save/close the popoverSalangi

© 2022 - 2024 — McMap. All rights reserved.