未以编程方式检测 Dismiss Popover

Posted

技术标签:

【中文标题】未以编程方式检测 Dismiss Popover【英文标题】:Not detecting Dismiss Popover programmatically 【发布时间】:2016-09-23 18:36:51 【问题描述】:

我正在以编程方式关闭弹出视图控制器。我如何在我的第一个视图控制器中检测到它?有没有办法将值从弹出窗口发送到第一个? 注意:popoverPresentationControllerDidDismissPopover 在以编程方式关闭时不起作用。 有什么提议吗?

这是我在主视图控制器中的代码:

    let addFriendsPopoverViewController = storyboard?.instantiateViewControllerWithIdentifier("HomeEmotionPopOver") as! EmotionPopOverViewController
    addFriendsPopoverViewController.modalInPopover = true
    addFriendsPopoverViewController.modalPresentationStyle =   UIModalPresentationStyle.Popover
    addFriendsPopoverViewController.preferredContentSize = CGSizeMake(100, 100)
    let popoverMenuViewController = addFriendsPopoverViewController.popoverPresentationController
    popoverMenuViewController!.permittedArrowDirections = .Any
    popoverMenuViewController!.delegate = self
    popoverMenuViewController!.sourceView = self.view
    let height = (self.tableView.rowHeight - HeartAttributes.heartSize / 2.0 - 10) + (self.tableView.rowHeight * CGFloat((sender.view?.tag)!)) - 50
    popoverMenuViewController!.sourceRect = CGRect(
        x: 30,
        y: height,
        width: 1,
        height: 1)
    presentViewController(
        addFriendsPopoverViewController,
        animated: true,
        completion: nil)   

在弹出视图控制器中,我从按钮 IBAction 中将其关闭:

     @IBAction func dismissPop(sender: AnyObject) 
    self.dismissViewControllerAnimated(true, completion: nil)


【问题讨论】:

请发布您的代码,以便重现您的麻烦。 我刚刚编辑了我的帖子,感谢您的帮助 那么从弹出框内的按钮关闭弹出框是否有效? 是的。但我无法从主视图控制器中检测到它。 我想发布一个答案,但当我看到 ColdLogic 更快时,我放弃了。这正是您所需要的。 【参考方案1】:

您提出问题的方式是您正在寻找主视图控制器上的一个函数,该函数在弹出框被解除时调用。

这在技术上发生在viewDidAppear(animated:)。但是,它不是一个完整的证明解决方案。如果你的弹出框没有覆盖全屏上下文,这个函数不会触发,所以它是一个不可靠的解决方案。

你真正想要的是从弹出框调用一个函数,提醒主视图控制器它已经完成/关闭。这可以通过委托协议轻松完成

protocol PopoverDelegate 
    func popoverDismissed()


class PopoverViewController 
    weak var delegate: PopoverDelegate?

    //Your Popover View Controller Code

将协议一致性添加到您的主视图控制器

class MainViewController: UIViewController, PopoverDelegate 
     //Main View Controller code

然后您需要将代理设置为,以使弹出框成为主视图控制器。

let addFriendsPopoverViewController = storyboard?.instantiateViewControllerWithIdentifier("HomeEmotionPopOver") as! EmotionPopOverViewController
addFriendsPopoverViewController.delegate = self
//The rest of your code

最后,当您关闭时,从您的弹出视图控制器中调用此委托函数。

@IBAction func dismissPop(sender: AnyObject) 
     dismissViewControllerAnimated(true, completion: nil)
     delegate?.popoverDismissed()

在你的主视图控制器中,实现委托方法

func popoverDismissed() 
    //Any code to run when popover is dismissed

【讨论】:

感谢您的快速回答,但我无法将代理设置为使弹出框成为主视图控制器。我收到一个错误:无法将委托分配给主视图控制器... 您是否将协议一致性添加到主视图控制器?我在答案中添加了示例代码以显示如何执行此操作。 非常感谢!您如何建议我将变量值从弹出框发送到主框? 可以修改popoverDismissed函数来传递变量。例如:func popoverDismissed(selectedString: String)。这个变量显然不需要是字符串,但这是一个例子。【参考方案2】:

诀窍是自己解除 segue,但让它看起来是用户启动的,这样它就可以被委托方法 popoverPresentationControllerDidDismissPopover() 检测到。

我通过向presentingViewController dismiss() 函数添加一个完成闭包并直接调用例程来做到这一点。

if let pvc = self.presentingViewController 
    var didDismiss : ((UIPopoverPresentationController) -> Void)? = nil
    if let delegate = popoverPresentationController?.delegate 
        // check it is okay to dismiss the popover
        let okayToDismiss = delegate.popoverPresentationControllerShouldDismissPopover?(popoverPresentationController!) ?? true
        if okayToDismiss 
            // create completion closure
            didDismiss = delegate.popoverPresentationControllerDidDismissPopover
        
    
    // use local var to avoid memory leaks
    let ppc = popoverPresentationController
    // dismiss popover with completion closure
    pvc.dismiss(animated: true) 
        didDismiss?(ppc!)
    

对我来说很好用。

【讨论】:

以上是关于未以编程方式检测 Dismiss Popover的主要内容,如果未能解决你的问题,请参考以下文章

附件未以编程方式发送到邮件中

Android:导航抽屉标题文本视图未以编程方式设置

UIView 未以编程方式显示在 UIScrollView 中

X 位置约束未以编程方式更新 - Xcode 中的 Swift

obj-c 应用程序未以编程方式本地化

如果应用程序未以编程方式安装 firebase 动态链接,则重定向到 iOS App Store