3

I want to always present a view controller in a popover on all devices and all orientations. I tried to accomplish this by adopting the UIPopoverPresentationControllerDelegate and setting the sourceView and sourceRect. The segue in the storyboard is configured as a Present As Popover segue. 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
}
Jordan H
  • 52,571
  • 37
  • 201
  • 351

1 Answers1

7

Implement the new (as of iOS 8.3) 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.

Joshua
  • 15,200
  • 21
  • 100
  • 172
  • 1
    This is no longer working in Xcode 7. The docs now state you can only return FullScreen and OverFullScreen from this method. – Jordan H Sep 03 '15 at 07:31
  • Sure, https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIAdaptivePresentationControllerDelegate_protocol/index.html#//apple_ref/occ/intfm/UIAdaptivePresentationControllerDelegate/adaptivePresentationStyleForPresentationController: – Jordan H Sep 03 '15 at 15:07
  • Actually, I was looking at the method similar to the one you've mentioned. The method including `traitCollection` isn't listed in the docs. But alas, this is not working for me because it's not calling that method upon present on the iPhone 6 Plus in landscape, however upon rotation it does call this method. In portrait, it does call it upon present but returning `.None` causes the presentation to be Over Full Screen instead of in a popover. – Jordan H Sep 03 '15 at 15:19
  • 3
    Never mind, this still works as expected. The problem was I was presenting it before setting the delegate (which is what the docs stated should be done). Setting the delegate of its `popoverPresentationController` before presenting it resolved the issue. – Jordan H Sep 03 '15 at 15:24
  • @Joey I have the same problem on iPhone 6 Plus, landscape mode, iOS 9 (on iOS 8 works fine), and I'm first setting the delegate, then showing. What could be the cause? – iOS Dev Jul 21 '16 at 08:00