web-dev-qa-db-ja.com

Swift:ポップオーバーがコールバックを却下

私のストーリーボードには2つのUIViewConrollersがあります:MainViewControllerSecondViewController。ユーザーがShow Popoverというボタンをタップすると、SecondViewControllerをポップオーバーとして表示します。

enter image description here

//MainViewController
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{

    if segue.identifier == "GoToSecondViewControllerSegue"
    {
        var vc = segue.destinationViewController as! SecondViewController
        var controller = vc.popoverPresentationController

        if controller != nil
        {
            controller?.delegate = self
            vc.inputTextDelegate = "I'm a popover!"
        }
    }
}

func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController) {
     println("done")
}

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle
{
    return .None
}

//SecondViewController
@IBAction func dismissPopover(sender: UIButton) {
     dismissViewControllerAnimated(true, completion: nil)
     //This dismisses the popover but does not notify the MainViewConroller
}

セグエのアンカーはボタンに接続されています: enter image description here

今私は2つの問題があります:

  1. ポップオーバー内のキャンセルボタンをタップすると、ポップオーバーは閉じられますが、MainViewController内のpopoverPresentationControllerDidDismissPopoverはトリガーされません。

  2. SecondViewControllerからMainViewController、テキスト値にデータを渡すにはどうすればよいですか?たとえば、UITextViewの.

7
Maysam

プロトコルと委任は、そのような問題の解決策です。私の場合、プロトコルを定義し、MainViewControllerをプロトコルに適合させました。

//SecondViewController
protocol MyDelegate{
    func DoSomething(text:String)
}

class SecondViewController: UIViewController {

 var delegate:GetTextDelegate?

 var inputTextDelegate:String = ""

 override func viewDidLoad() {
    newText.text = inputTextDelegate
 }

 @IBAction func dismissPopover(sender: UIButton) {
        dismissViewControllerAnimated(true, completion: nil)
       //This dismisses the popover but does not notify the  MainViewConroller
 }
 @IBAction func doneButtonAction(sender: UIButton) {
    if let delegate = self.delegate {
        delegate.DoSomething(newText.text)
        self.dismissViewControllerAnimated(true, completion: nil)
    }
 }
}

class MainViewController: UIViewController, UIPopoverPresentationControllerDelegate, MyDelegate {


    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
    {

        if segue.identifier == "GoToSecondViewControllerSegue"
        {
            var vc = segue.destinationViewController as! SecondViewController
            vc.delegate = self
            vc.inputTextDelegate = "I'm a popover!"
        }
    }

    func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController) {
        //...
    }

 func DoSomething(text: String) {
     //Do whatever you want
     println(text)
 }

}
8
Maysam

または、もっと簡単に言えば、ポップオーバーを手動で閉じるときに、iOSのデリゲートメソッドを手動で呼び出すだけです。

    dismissViewControllerAnimated(true, completion: nil)
    popoverPresentationController?.delegate?.popoverPresentationControllerDidDismissPopover?(popoverPresentationController!)
11
Luke Bartolomeo

PopOverDelegateとして自分自身を設定する必要があります。これは、宛先のpopoverPresentationControllerで行う必要があります。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    segue.destination.popoverPresentationController?.delegate = self
}

次に、ViewControllerにデリゲートを実装することを宣言します。

extension FormViewController: UIPopoverPresentationControllerDelegate {

    func popoverPresentationControllerDidDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) {
        printBreadcrumb("Dismissed popover")
    }

}
10
doozMen