问题
In my iOS 8 app, this popover segue appears correctly on all devices in all orientations except for iPhone 6 Plus landscape:
This is how it looks on iPhone 6 Plus landscape (it is stretching almost from top to bottom):
And when it displays like this, clicking outside of the view doesn't dismiss it (although Cancel does work). Rotating back to portrait gets it back to normal.
All of the constraints in this UIViewController
are installed on all size classes.
When debugging values in viewDidAppear:
I see the following:
- po self.view: frame = (0 0; 250 394)
- po self.preferredContentSize (width = 250, height = 160)
What is causing the view's height to jump to 394?
I'm actually having the same issue with another popover segue in iPhone 6 Plus landscape as well. (And in case there was curiosity, I'm using a VC instead of 'UIAlertController' here because of the validation requirements of the UITextField
displayed don't work well with UIAlertController
.)
Edit to include my popover code:
This code is found in prepareForSegue:
FavoriteNameViewController *nameVC = segue.destinationViewController;
UIPopoverPresentationController *popPC = nameVC.popoverPresentationController;
popPC.delegate = self;
nameVC.delegate = self;
nameVC.view.center = self.originalContentView.center;
And then the delegate method:
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
And here is the segue definition in Xcode:
回答1:
What you're seeing is not a popover. It's a normal presented view. By default, a popover appears as a popover on iPad, but as a presented view on iPhone — including the iPhone 6 plus. On other iPhones, this presented view is fullscreen - it covers everything. But the iPhone 6 is so wide that they don't do that, so it appears in the middle of the screen at a standard width (the width of a smaller iPhone).
Thus, the preferred content size has no effect. This isn't a popover. Presented view controller views are given a standard size, and this one is no exception.
However, you can have the popover appear as a popover on iPhone. To do so:
Set a delegate for the popover view controller's
popoverPresentationController
before presenting it.In the delegate, implement
adaptivePresentationStyleForPresentationController:
and return.None
.
However, this is apparently not working on iPhone 6 Plus in landscape mode; the popover is not "adapting". I would describe this as a bug!
EDIT In iOS 9, the problem is solved! Implement the new delegate method adaptivePresentationStyleForPresentationController:traitCollection:
to return .None
and you'll get a popover under all circumstances, including the iPhone 6 Plus in landscape. Here's a complete working example where the popover is created and summoned in code in response to a button tap:
@IBAction func doButton(sender: AnyObject) {
let vc = MyViewController()
vc.preferredContentSize = CGSizeMake(400,500)
vc.modalPresentationStyle = .Popover
if let pres = vc.presentationController {
pres.delegate = self
}
self.presentViewController(vc, animated: true, completion: nil)
if let pop = vc.popoverPresentationController {
pop.sourceView = (sender as! UIView)
pop.sourceRect = (sender as! UIView).bounds
}
}
func adaptivePresentationStyleForPresentationController(
controller: UIPresentationController,
traitCollection: UITraitCollection)
-> UIModalPresentationStyle {
return .None
}
来源:https://stackoverflow.com/questions/31275151/why-isnt-preferredcontentsize-used-by-iphone-6-plus-landscape