Dismiss Popover after touch

2019-02-07 06:07发布

问题:

I've created a popover inside my MainViewController when some button its touched using the UIPopoverPresentationController and set like it's delegate like it's showed in the WWDC 2014, in the following way :

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)        
   }  
}

The popover have a View inside it and when the View it's clicked with a Tap Gesture Recognizer I show LastViewController using a modal segue, the modal segue is created through the Interface Builder, not in code using an action to present the another LastViewController

Once the LastViewController is dismissed and I'm back in the MainViewController the popover remains open.

Inside the PopOverController I only have the default code nothing more.

LastViewController.swift

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

The above code is used to dismiss the LastViewController once the button inside is touched.

Storyboard

How can I dismiss the popover once the another LastViewController it's visible, or before the another LastViewController should be opened?

Thanks in advance

回答1:

I have already answer same problem over here.
There scenario is different but solution is same

You have to write code for dismiss presented view controller on completion of current view controller.
Write below code on your dismissVIew method of LastViewController.swift

 var tmpController :UIViewController! = self.presentingViewController;

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


Download link



回答2:

In your button action on the FinalViewController, have you tried:

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


回答3:

here is how I would do it.

I usually use lazy initialization for the PopoverViewController and it's 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
}()

inside my contentViewController I hold a reference to the UIPopoverController.

var popoverVC: UIPopoverController!

then when I show the popover i just assign the popoverController to the 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)
}

finally I dismiss the Popover programmatically inside an @IBAction

@IBAction func dismissPopover(sender: AnyObject) {
    popoverVC.dismissPopoverAnimated(true)
}


回答4:

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.

As far as I understand from what you say, you should be able to call dismissViewControllerAnimated(_:completion:) from the action associated to your tap gesture recogniser. This will dismiss the popover you presented calling:

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

You can call this method on the popover view controller itself, depending on what is more convenient for you:

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.



回答5:

Inside the viewcontroller you can override viewWillAppear()

Inside of this block dimiss it

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

But the above code assumes you have a reference to the PopOver object, which I don't think is good practice based on how you described the problem.

Rather, why not have the viewcontroller that created the PopOver be responsible for destroying it. Put this in the class that listens for the button touch (which I also assumes creates the PopOver as well)

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