在其他地方点击时关闭弹出视图控制器

Posted

技术标签:

【中文标题】在其他地方点击时关闭弹出视图控制器【英文标题】:Dismiss popover viewController when tapped elsewhere 【发布时间】:2017-01-12 14:40:49 【问题描述】:

我在 UITableView 上展示了一个弹出视图控制器。在弹出窗口之外点击时如何关闭它?我试图从 didSelectRow 方法中调用它,但没有检测到点击。有什么建议吗? 谢谢! 这是我的代码:

    let addFriendsPopoverViewController = storyboard?.instantiateViewController(withIdentifier: "HomePopOver") as! HomePopOverViewController
    addFriendsPopoverViewController.index = (sender.tag)!
    addFriendsPopoverViewController.delegate = self
    addFriendsPopoverViewController.isModalInPopover = true
    addFriendsPopoverViewController.modalPresentationStyle =   UIModalPresentationStyle.popover
    addFriendsPopoverViewController.preferredContentSize = CGSize(width: 210, height: 40)
    let popoverMenuViewController = addFriendsPopoverViewController.popoverPresentationController
    popoverMenuViewController!.permittedArrowDirections = .down
    popoverMenuViewController!.delegate = self
    popoverMenuViewController!.sourceView = self.view
    popoverMenuViewController!.sourceRect = CGRect(
        x: UIScreen.main.bounds.width  - 105,
        y: 50,
        width: 1,
        height: 1)
    present(
        addFriendsPopoverViewController,
        animated: true,
        completion: nil)

【问题讨论】:

你是如何展示弹出框的? 我正在通过 tableView 中的按钮展示它。 (点击此按钮时) 演示代码是多少? 我刚刚编辑了我的帖子。请检查一下! 如果你想让isModalInPopover在外面点击时关闭,不要设置true 【参考方案1】:

UIPopoverController 中显示或使用UIModalPresentationPopover 显示的视图控制器将在用户在弹出框外点击时自动关闭,除非您设置了isModalInPopover 或实施了阻止它的委托方法。

如果发生这种情况时您需要运行一些代码,那么您也需要实现一个委托方法。

具体的方法取决于您使用的是UIPopoverController 还是UIModalPresentationPopover。您问题上的标签建议使用前者,但这是一种非常老式(且已弃用)的方法。

【讨论】:

是的,它是一个 UIModalPresentationPopover。我怎样才能检测到它之外的触摸并关闭它? @MarcIbrahim 为什么需要检测它之外的触摸?它会自动关闭。 这就是问题所在。它不会自动关闭! 你将 isModalInPopover 设置为 true - 不要那样做!【参考方案2】:

即使您找到了答案,我还是想分享我的解决方案,因为我遇到了同样的问题,在我花了一些时间弄清楚之后,我发现了问题所在。这实际上不是因为缺少某些东西,而是因为某些东西是徒劳的。

虽然我不知道为什么会发生这种情况,但是如果在您的代码中实现了以下方法,则可能会导致弹出框 not 通过点击UIBarButtonItem 本身以外的任何其他位置来关闭。

    func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) 
        popoverPresentationController.permittedArrowDirections = .any
        popoverPresentationController.barButtonItem = UIBarButtonItem(customView: categoryButton)
    

这是我为 popover 所做的其余实现:

extension SearchViewController:UIPopoverPresentationControllerDelegate 

func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle 
    return .none


func presentPopover(sender: UIButton) 
    let popoverContentController = PopoverCategoryViewController()
    let nav = UINavigationController(rootViewController: popoverContentController)
    nav.modalPresentationStyle = UIModalPresentationStyle.popover
    nav.isNavigationBarHidden = true
    let popover = nav.popoverPresentationController
    popover?.backgroundColor = ChaptifyColor.backgroundGray
    popover?.delegate = self
    popover?.sourceView = sender
    popover?.sourceRect = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: sender.bounds.width, height: sender.bounds.height))
    popoverContentController.preferredContentSize = CGSize(width: 300, height: 300)
    self.present(nav, animated: true, completion: nil)


【讨论】:

这也是我的问题。所以基本上,如果你使用barButtonItem 设置源,那么弹出框只会在再次点击该栏按钮时消失。

以上是关于在其他地方点击时关闭弹出视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

在弹出视图之外的任何地方点击时关闭弹出视图,包括按钮、文本字段等

iOS 弹出框在关闭后不会消失

尝试关闭弹出视图控制器 Swift 时没有任何反应

弹出其他视图控制器时如何更改弹出视图大小

触摸整个应用程序时如何关闭键盘

弹出窗口关闭时如何在主视图控制器中快速运行代码