web-dev-qa-db-ja.com

タッチ後にポップオーバーを閉じる

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を閉じるために使用されます。

ストーリーボード

enter image description here

別のLastViewControllerが表示された後、または別のLastViewControllerを開く前に、どうやってポップオーバーを閉じることができますか?

前もって感謝します

8
Victor Sigler

hereで同じ問題にすでに回答しています。
シナリオは異なりますが、解決策は同じです

現在のビューコントローラーの完了時に、表示されたビューコントローラーを閉じるためのコードを記述する必要があります。
dismissVIewメソッドのコードの下にLastViewController.Swift

 var tmpController :UIViewController! = self.presentingViewController;

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


ダウンロード リンク

18
Jageen

FinalViewControllerのボタンアクションで、次のことを試しましたか。

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

ここに私がそれをする方法があります。

私は通常、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内のプログラムでポップオーバーを閉じます

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

ビューコントローラー内で、viewWillAppear()をオーバーライドできます。

このブロックの内側はそれを無視します

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

しかし、上記のコードは、PopOverオブジェクトへの参照があることを前提としています。これは、問題をどのように説明したかに基づいては適切な方法ではないと思います。

むしろ、PopOverを作成したビューコントローラーがそれを破棄する責任を負わないようにしてください。これをボタンタッチをリッスンするクラスに配置します(これもPopOverを作成すると想定しています)。

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

ポップオーバーの内部にはビューがあり、そのビューがタップジェスチャー認識機能でクリックされると、モーダルセグエを使用して別のViewControllerを表示します。

あなたの発言から私が理解する限り、タップジェスチャー認識機能に関連付けられたアクションから dismissViewControllerAnimated(_:completion:) を呼び出すことができるはずです。これにより、提示したポップオーバーが呼び出されなくなります。

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

このメソッドは、何が便利かによって、ポップオーバービューコントローラー自体で呼び出すことができます。

提示するビューコントローラは、提示したビューコントローラを閉じる責任があります。提示されたビューコントローラ自体でこのメソッドを呼び出すと、提示されたビューコントローラにメッセージが自動的に転送されます。

0
sergio

@Jageenの回答に基づく

Swift 4.2

let tmpController :UIViewController! = self.presentingViewController;

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