

Popoverから戻ってきたときに感知するにはどうすればいいのでしょうか。  
viewWillAppearなどは使えず、  
[swiftで画面遷移時の関数の実行](https://ja.stackoverflow.com/questions/11879/swift%E3%81%A7%E7%94%BB%E9%9D%A2%E9%81%B7%E7%A7%BB%E6%99%82%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%AE%E5%AE%9F%E8%A1%8C)  
を参考にしてdismissした時に関数を実行させるようにしましたが、戻ってくる側のviewControllerの変数を使おうとするとnilが返ってきてしまいます。  
ご存知の方がいらっしゃったらご教授ください。

Code

[code]

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        //セルの選択解除
        tableView.deselectRow(at: indexPath, animated: true)
    
        let back = storyboard!.instantiateViewController(withIdentifier: "View") as? ViewController
        back?.doAnything(text: text[indexPath.row])
        self.dismiss(animated: true, completion: {() in back?.received = self.text[indexPath.row]})
    }
    
[/code]

もう1つの方

[code]

    var number:Int!
    
    func doAnything(text: String) {
        print(text)
        switch text {
        case "1":
            let activityItem:[Int] = number //これがnilになる
            let activityVC = UIActivityViewController(activityItems: activityItem, applicationActivities: nil)
            self.present(activityVC, animated: true, completion: nil)
    
            print(url)
    
        case "2":
            break
        case "3":
            break
        case "4":
            break
        case "5":
            break
        default:
            break
        }
    }
    
[/code]


CC BY-SA 4.0
2019-04-12T06:23:39.670
54117
2019-04-12T14:36:45.050
2019-04-12T09:32:11.283
32892
32892
question
swift xcode swift5
Popoverから戻ってきた時実行する


確認ですが、あなたのコードは現在このようになっていることを想定しています。

呼び出し側のview controller:

[code]

    class ViewController: UIViewController {
    
        //...
    
        //どこかのアクションメソッドからPopoverを`present`で表示している...ものと想定
        @IBAction func someAction(_ sender: Any) {
            //...
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let popover = storyboard.instantiateViewController(withIdentifier: "Popover") as! PopoverViewController
            //...
            self.present(popover, animated: true, completion: nil)
        }
    
        var received: String? = nil
    
        var number: Int!
    
        func doAnything(text: String) {
            print(text)
            switch text {
            case "1":
                let activityItem: [Int] = [number]  //<- `[number]` ?
                let activityVC = UIActivityViewController(activityItems: activityItem, applicationActivities: nil)
                self.present(activityVC, animated: true, completion: nil)
    
                //print(url) //<- What is `url`?
    
            case "2":
                break
            case "3":
                break
            case "4":
                break
            case "5":
                break
            default:
                break
            }
        }
    }
    
[/code]

Popover用のview controller:

[code]

    class PopoverViewController: UITableViewController {
    
        //...
    
        var text: [String] = []
    
        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            //セルの選択解除
            tableView.deselectRow(at: indexPath, animated: true)
    
            let back = storyboard!.instantiateViewController(withIdentifier: "View") as? ViewController
            back?.doAnything(text: text[indexPath.row])
            self.dismiss(animated: true, completion: {() in back?.received = self.text[indexPath.row]})
        }
    
        //...
    }
    
[/code]

あなたが示されたコード、一部コンパイルが通らない部分があったので修正してあります。質問用に少し書き換えられたのかもしれませんが、そのせいで根本的に違う結果になってしまう可能性もあるので注意してください。また、一部推定も含まれています。実際と大きく異なっている点があれば、ご質問に情報を追記するなり、コメントするなりしてお知らせください。

* * *

と言うわけで、あなたのコードで致命的に誤っているのはここだと思われます。

[code]

        let back = storyboard!.instantiateViewController(withIdentifier: "View") as? ViewController
    
[/code]

Popoverから戻り先のview
controllerにアクセスするのに、新しいインスタンスを作成してしまってはいけません。このコードは(同じ`ViewController`クラスではあるけれど)新たにインスタンスを作成するものであり、作成されたインスタンスは「戻り先」のview
controllerとは別物です。

いろいろとやり方は考えられるでしょうが、一番確実なのは戻り先のview
controllerを直接プロパティとしてPopover側に持たせてやることでしょう。

Popover側はこんな感じ。

[code]

    protocol PopoverViewControllerDelegate: class {
        var received: String? {get set}
        func doAnything(text: String)
    }
    class PopoverViewController: UITableViewController {
    
        //...
    
        weak var delegate: PopoverViewControllerDelegate?
    
        var text: [String] = []
    
        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            //セルの選択解除
            tableView.deselectRow(at: indexPath, animated: true)
    
            delegate?.doAnything(text: text[indexPath.row])
            self.dismiss(animated: true) {
                self.delegate?.received = self.text[indexPath.row]
            }
        }
    
        //...
    }
    
[/code]

典型的なdelegateパターンということになるので、「戻り先」を`delegate`として、呼び出したい機能(メソッドやプロパティ)をprotocolにしてあります。

呼び出し側はこんな風になるでしょう。

[code]

    //↓`PopoverViewControllerDelegate`への適合を追加
    class ViewController: UIViewController, PopoverViewControllerDelegate {
    
        //...
    
        @IBAction func someAction(_ sender: Any) {
            //...
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let popover = storyboard.instantiateViewController(withIdentifier: "Popover") as! PopoverViewController
            popover.delegate = self //<- Popoverの呼び出し時にdelegateを設定
            //...
            self.present(popover, animated: true, completion: nil)
        }
    
        var received: String? = nil
    
        var number: Int? //<-未初期化の可能性のある変数にImplicitlyUnwrappedOptionalは使わない
    
        func doAnything(text: String) {
            //`number`が非nilであることをguardで確認
            guard let number = number else {
                print("`number` is nil")
                return
            }
            print(text)
            //...
        }
    }
    
[/code]

`number`のように呼び出しの順序によっては未初期化状態になる可能性のある変数にImplicitlyUnwrappedOptionalを使うべきではありませんので、普通のOptionalに変え、使う前に`guard`で非nilのチェックを入れています。

* * *

最初に書いたように一部推定を含んでいるので、全く使い物にならないものをお見せしてしまっている可能性もありますが、うまくあなたのコードに適用できそうでしたら、お試しください。


CC BY-SA 4.0
2019-04-12T14:36:45.050
54124
2019-04-12T14:36:45.050
13972
54117
answer