情节提要弹出框已关闭,未调用委托方法

Posted

技术标签:

【中文标题】情节提要弹出框已关闭,未调用委托方法【英文标题】:Storyboard popover dismissed, delegate methods not called 【发布时间】:2016-05-03 03:24:51 【问题描述】:

我有一个视图控制器,它使用情节提要 segue 在弹出窗口中呈现。

在呈现视图控制器中,我有以下代码:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
    if let svc = segue.destinationViewController as? SettingsViewController 
        svc.popoverPresentationController?.delegate = self
    

然而,事实证明,呈现的视图控制器,即使它显示为一个弹出框,也有一个 modalPresentationStyle'.Modal,因此是一个 nil popoverPresentationController。诡异的!

所以,我更新代码如下:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
    if let svc = segue.destinationViewController as? SettingsViewController 
        svc.modalPresentationStyle = .Popover
        svc.popoverPresentationController?.delegate = self
    

svc.popoverPresentationController 委托现在设置为 OK,但如果弹出框被用户点击外部关闭,则不会调用任何 UIPopoverPresentationControllerDelegate 委托方法(例如 popoverPresentationControllerShouldDismissPopover。我错过了什么?

【问题讨论】:

可能是个愚蠢的问题,你确定故事板中的 segue 设置为“Present as Popover”吗? 是的,当然 - 它正确地显示为弹出框(甚至在设置 svc.modalPresentationStyle = .Popover 之前就已经显示)。值得检查! 有一点很奇怪,它应该说“Present as Popover”,因为应该不推荐使用“Popover”,但我认为这不是问题...... “Present as Popover”是启用尺寸等级时的一个选项。没有它,它只是“Popover” 当时是svc.popoverPresentationController 非零吗?否则,它会默默地不设置委托。 【参考方案1】:

在这种情况下不需要委托。如果presentingViewController(无论vc 包含弹出框)只是覆盖:

斯威夫特 4

override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) 
    print("Dismiss: \(String(describing: self.presentedViewController))")
    super.dismiss(animated: flag, completion: completion)


斯威夫特 3

override func dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?) 
    // Before calling super get a handle on which controller is being dismissed
    print("Dismiss: \(self.presentedViewController)")
    super.dismissViewControllerAnimated(flag, completion: completion)

无论如何解除,您都会收到通知。您也不需要在prepareForSegue: 中设置任何其他变量/设置(至少要处理此交互)。

【讨论】:

这是唯一的答案,所以获得奖励。不过好像不太对劲,不知何故 @AshleyMills 很好奇你为什么不这么认为?随着弹出框、警报和操作表成为实际容器(从 ios 8 开始),而不是它们自己的独立视图元素(例如窗口),它实际上确实有意义。弹出框现在的功能与普通 VC 相同。 抱歉,并不是说您的回答不好。只是我希望有人知道为什么 popoverPresentationControllerDelegate 方法没有被解雇。在我的情况下,弹出框是从导航栏中的 UIBarButtonItem 呈现的,因此 navController 需要子类化来实现您的解决方案【参考方案2】:

遇到了同样的问题,在阅读了文档后,我意识到您需要致电:

[self presentViewController:myPopoverViewController animated: YES completion: nil];

为了调用委托方法。

完整的 sn-p 如下,在我的 -(void)prepareForSegue:sender 方法中运行:

// Present the view controller using the popover style.
myPopoverViewController.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:myPopoverViewController animated: YES completion: nil];

// Get the popover presentation controller and configure it.
UIPopoverPresentationController *presentationController =
         [myPopoverViewController popoverPresentationController];
presentationController.permittedArrowDirections =
         UIPopoverArrowDirectionLeft | UIPopoverArrowDirectionRight;
presentationController.sourceView = myView;
presentationController.sourceRect = sourceRect;

https://developer.apple.com/documentation/uikit/uipopoverpresentationcontroller

【讨论】:

以上是关于情节提要弹出框已关闭,未调用委托方法的主要内容,如果未能解决你的问题,请参考以下文章

在表格视图中选择项目后无法关闭弹出框

iOS8 在情节提要中设置弹出框大小

如何使用情节提要从自定义 uitableviewcell 正确启动弹出框转场

试图关闭故事板呈现的弹出框

在 iOS8 中检测弹出框关闭

在哪种情况下应该在情节提要中使用 Popover segue?