

swiftでアプリ開発をしています。

画面A・画面Bとありまして  
画面Aから画面Bが呼ばれます。  
で、画面Bから画面Aに戻った時に、画面Aの関数を実行したいのですが  
方法がわかりません。  
画面Aから画面Bは下記のようにStoryboard IDを使ってモーダル表示しています。  
【画面A】

[code]

    var selfStoryboard: UIStoryboard?
    selfStoryboard = self.storyboard
    nex = selfStoryboard!.instantiateViewControllerWithIdentifier("Storyboard_ID") as UIViewController
    self.presentViewController(nex, animated: true, completion: nil)
    
[/code]

画面Bでは下記のように記述し画面を閉じています。  
【画面B】

[code]

    self.dismissViewControllerAnimated(true, completion:nil)
    
[/code]

このようにして画面を閉じた後に、画面Aの特定な関数を実行するにはどうしたらよいのでしょうか。


CC BY-SA 3.0
2015-06-30T07:56:05.407
11879
2023-08-23T07:09:16.077
2016-12-30T11:12:22.473
76
9987
question
swift iphone
swiftで画面遷移時の関数の実行


モーダルによる画面遷移の場合、遷移元のViewControllerは、`UIViewController`クラスのプロパティ`presentingViewController`で取得できます。  
遷移元のViewControllerを、`BaseViewController`、呼びたい`BaseViewController`のメソッドを、`func
doAnything()`とすると

[code]

    if let controller = self.presentingViewController as? BaseViewController {
        controller.doAnyThing()
    }
    
[/code]

> 画面Bから画面Aに戻った時に、画面Aの関数を実行したい

戻ったときに実行されるのではなく、上のコードは戻る前に実行されますから、厳密にいうと、あなたのご要望には沿っておりません。それで問題ないとは思いますが、どうしても「閉じた後」でなければならない事情があるのなら、`dismissViewControllerAnimated()`の引数`completion`を使います。

[code]

    let controller = self.presentingViewController as? BaseViewController
    self.dismissViewControllerAnimated(true, completion: {
        controller?.doAnything()
    })
    
[/code]

クロージャ内で`self.presentingViewController`を使うと、うまく動かないので、こういう書き方になっています。


CC BY-SA 3.0
2015-07-01T00:37:20.883
11910
2015-07-01T22:25:32.817
2015-07-01T22:25:32.817
7362
7362
11879
answer


viewWillAppear関数を使えばできると思います。

[code]

    class ViewController: UIViewController {
        override func viewWillAppear(_ animated: Bool) { // 戻ってきた時に実行されます
            super.viewWillAppear(animated)
            // ここにコードを記載
        }
    }
    
[/code]

注意: ただし、このやり方だと、一番最初画面Aが表示された時にも実行されてしまいます。  
ですので、

[code]

    class ViewController: UIViewController {
        var isBack = false
        override func viewWillAppear(_ animated: Bool) { // 戻ってきた時に実行されます
            super.viewWillAppear(animated)
            // ここにコードを記載
            if isBack {
                // ここにコードを記載
            }
            isBack.toggle()
        }
    }
    
[/code]

のように、変数を定義しておき、条件分岐を使用して戻ったか確かめればいいと思います。  
ただ、このやり方ですと

[code]

    C -> A -> B
    
[/code]

のような構造になっていた場合に、

[code]

    C -> *A -> C -> */A
    
[/code]

このような順番で遷移したときには *マーク でviewWillAppearが実行されますが、/マーク
のところで戻ってきたときに実行されるはずの処理が実行されてしまうので、そのような場合にはBから値渡しをするなど、別のやり方が必要になります。


CC BY-SA 4.0
2020-05-05T01:32:04.787
66298
2021-04-01T08:11:48.970
2021-04-01T08:11:48.970
39579
39579
11879
answer