触摸后关闭 Popover

Dismiss Popover after touch

我在我的 MainViewController 中创建了一个弹出窗口,当使用 UIPopoverPresentationController 触摸某个按钮并设置为委托时,就像在 WWDC 2014 中显示的那样,方法如下:

MainViewController.swift

class MainViewController : UIViewController, UIPopoverPresentationControllerDelegate {

   @IBAction func showPopover(sender: AnyObject) {

      var popoverContent = self.storyboard?.instantiateViewControllerWithIdentifier("PopOverViewController") as UIViewController

      popoverContent.modalPresentationStyle = UIModalPresentationStyle.Popover
      var popover = popoverContent.popoverPresentationController

      popoverContent.preferredContentSize = CGSizeMake(250, 419)
      popover!.delegate = self
      popover!.sourceView = self.view
      popover!.sourceRect = CGRectMake(180,85,0,0)

      self.presentViewController(popoverContent, animated: true, completion: nil)        
   }  
}

弹出窗口内部有一个视图,当使用点击手势识别器单击视图时,我使用模态转场显示LastViewController,模态转场是通过界面生成器创建的,而不是在代码中使用展示另一个的动作 LastViewController

关闭 LastViewController 并且我返回 MainViewController 后,弹出窗口保持打开状态。

PopOverController里面我只有默认代码而已。

LastViewController.swift

@IBAction func dismissVIew(sender: AnyObject) {        
    self.dismissViewControllerAnimated(true, completion: nil)
}

上面的代码用于在触摸内部按钮后关闭 LastViewController

Storyboard

如何在另一个 LastViewController 可见时或在打开另一个 LastViewController 之前关闭弹出窗口?

提前致谢

在 viewcontroller 中你可以覆盖 viewWillAppear()

在此块内部将其关闭

 override public  func viewWillAppear(animated: Bool)
    {
        super.viewWillAppear(animated)
        _viewToDismiss.removeFromSuperView()
    }

但是上面的代码假定您有对 PopOver 对象的引用,根据您对问题的描述,我认为这不是一个好的做法。

相反,为什么不让创建 PopOver 的 viewcontroller 负责销毁它。把它放在监听按钮触摸的 class 中(我还假设它也创建了 PopOver)

- (void)viewWillDisappear:(BOOL)animated 
{
   _popOver.removeFromSuperView()
}

The popover have a View inside it and when the View it's clicked with a Tap Gesture Recognizer I show another ViewController using a modal segue.

据我从你所说的理解,你应该能够从与你的点击手势识别器相关联的动作中调用 dismissViewControllerAnimated(_:completion:)。这将关闭您调用的弹出窗口:

self.presentViewController(popoverContent, animated: true, completion: nil)        

您可以在弹出视图控制器本身上调用此方法,具体取决于您更方便的方式:

The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, it automatically forwards the message to the presenting view controller.

我已经在 here 上回答了同样的问题。
场景不同但解决方案相同

您必须编写代码以在当前视图控制器完成时关闭呈现的视图控制器。
LastViewController.swift

的 dismissVIew 方法上写下代码
 var tmpController :UIViewController! = self.presentingViewController;

        self.dismissViewControllerAnimated(false, completion: {()->Void in
            println("done");
            tmpController.dismissViewControllerAnimated(false, completion: nil);
        });


下载 link

在最终 ViewController 上的按钮操作中,您是否尝试过:

@IBAction func dismissMe() {
//this should tell the popover to tell the main view controller to dismiss it.
    self.presentingViewController!.presentingViewController!.dismissViewControllerAnimated(false, completion: nil)
}

这是我的做法。

我通常对 PopoverViewController 和它的 ContentViewController 使用惰性初始化

lazy var popoverVC: UIPopoverController = {
    let vc = UIPopoverController(contentViewController: self.contentVC)

    vc.delegate = self

    return vc
}()


lazy var contentVC: UIViewController = {
    let vc = self.storyboard?.instantiateViewControllerWithIdentifier("ContentViewController") as UIViewController

    vc.modalInPopover = true

    return vc
}()

在我的 contentViewController 中,我持有对 UIPopoverController 的引用。

var popoverVC: UIPopoverController!

然后当我显示弹出窗口时,我只是将 popoverController 分配给 contentViewController

@IBAction func showPopover(sender: UIButton) {
    contentVC.popoverVC = self.popoverVC

    let viewCenterRect = self.view.convertRect(self.view.bounds, toView: self.view)

    popoverVC.presentPopoverFromRect(CGRectMake(CGRectGetMidX(viewCenterRect), CGRectGetMidY(viewCenterRect), 1, 1), inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.allZeros, animated: true)
}

最后我在 @IBAction

中以编程方式关闭 Popover
@IBAction func dismissPopover(sender: AnyObject) {
    popoverVC.dismissPopoverAnimated(true)
}

基于@Jageen 的回答

Swift 4.2

let tmpController :UIViewController! = self.presentingViewController;

self.dismiss(animated: false, completion: {()->Void in
    print("done");
    tmpController.dismiss(animated: false, completion: nil);
});