问题
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
回答1:
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.
回答2:
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)
}
回答3:
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.)
回答4:
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.
来源:https://stackoverflow.com/questions/30378249/uimodalpresentationpopover-for-iphone-6-plus-in-landscape-doesnt-display-popove