iPhone 6 Plus横屏下使用UIModalPresentationPopover无法显示弹出窗口

35

我希望在所有设备和方向上始终以弹出窗口的形式显示一个 ViewController。我尝试采用 UIPopoverPresentationControllerDelegate 并设置 sourceViewsourceRect 来实现这一点。

对于所有设备和方向,这非常有效,但 iPhone 6 Plus 在横向模式下除外。在这种情况下,视图控制器从屏幕底部滑动起来,以表单方式显示。我应该如何防止这种情况发生,以便它总是以弹出窗口的形式显示?

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 }

所有设备都在 iOS 8.2 或更高版本下运行。

4个回答

82

实现 UIAdaptivePresentationControllerDelegate 的新方法 adaptivePresentationStyleForPresentationController:traitCollection::

- (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告诉展示控制器使用原始的展示样式,这在您的情况下将显示一个弹出窗口。


1
好的,我忘记了8.3的委托方法已经改变。 - user4151918
1
@PetahChristian 谢谢!是的,这是一个相当安静的变化,似乎除了 API 差异之外没有记录。 - Joshua
@Joshua 是的!我已经实现了 - (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller { return UIModalPresentationNone; } 但是新的API解决了我的问题,谢谢您先生! - Loegic
13
由于某些原因,我需要读三遍才能看到该委托方法中的: traitCollection部分。起初我以为“是的,我已经实现了它”,因为较短的版本适用于其他设备。谢谢!...我一直在纳闷为什么它不适用于6+,原来问题如此简单。 - digitalHound
2
为什么苹果在6/7 Plus横屏时做了这个特定的更改?为什么不只是显示一个弹出窗口,如果那是你请求的呢? - bartzy
谢谢你!如果我的最低iOS是9,那么我是否需要实现这个没有traitCollection的缩短版本,还是只实现这个方法就可以了? - Lucas P.

7
在Swift 3中,如果您实现了原始的adaptivePresentationStyle方法,只需添加以下代码即可实现:
func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
    return adaptivePresentationStyle(for: controller)
}

2
一个提示给那些遇到问题的人:

这个

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

这不同于这个。
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController: (UIPresentationController * ) controller {
    return UIModalPresentationNone;
}

后者不会像前者那样被调用/工作。

1

苹果公司根据iPhone 6 Plus的大小类别设计了演示文稿的行为。

要防止在iPhone 6 Plus上出现模态演示文稿,您需要覆盖特性集合(水平大小)。

您应该能够设置呈现控制器的overrideTraitCollection属性:

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

抱歉,我还没有学习Swift,所以只能使用Objective C。


抱歉,对我来说它没有起作用,我无法覆盖traitCollection,"mean to be"弹出窗口在iPhone 6 Plus横屏模式下仍然呈现为页面表格。 - Loegic
虽然我很感兴趣,但今天早上我没有时间去研究这个问题。我可以在问题上提供悬赏以吸引一些关注。 :) - user4151918
我看到了,谢谢 :) traitCollection重载似乎是个好主意,但它似乎被忽略了。 - Loegic
添加在设置modalPresentationStyle = UIModalPresentationPopover之前的这行代码会覆盖trait collection,但是我认为UIPopoverPresentationController并不知道这个变化,因此仍然显示没有导航栏来保存/关闭弹出窗口。 - Jorge Balleza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接