Swift4 にて NavigationController の「戻る」にコールバックをつける方法

画面遷移時のイベント発火

画面遷移した時に ViewController 間での値の受け渡しや初期化などするために、
viewDidLoad(), viewWillAppear() など色んなイベントが用意してある。
下記は NavigationController の親子間でイベント発火させるサンプルコード。

ParentViewController.swift

  • ボタンを押すと NavigationController の pushViewController() で画面遷移する。
  • 遷移先の ChildViewController には didBack() がある。
import UIKit

class ParentViewController: UIViewController {
    
    @IBOutlet weak var button: UIButton!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        button.addTarget(self, action: #selector(self.onTouchDown(_:)), for: .touchDown)
    }
    

    // MARK: - Target Button
    
    @objc func onTouchDown(_ sender: UIButton) {
        let storyboard: UIStoryboard = UIStoryboard(name: "Child", bundle: nil)
        let vc: ChildViewController = storyboard.instantiateViewController(withIdentifier: "Child") as! ChildViewController
        vc.didBack = {
            print("did back")
        }
        self.navigationController?.pushViewController(vc, animated: true)
    }
    
}

ChildViewController.swift

  • didMove() を使う。
  • コールバック関数は didBack()
  • スワイプで戻るか、メニュー上部の「」で戻った場合に、 didBack() が呼ばれる。
import UIKit

class ChildViewController: UIViewController {
    
    var didBack: (() -> Void)?
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    // NavigationController の「戻る」、「進む」で didMove() が呼ばれる。
    override func didMove(toParent parent: UIViewController?) {
        if parent == nil {
			// 「戻る」場合の処理はここから
            super.didMove(toParent: nil)
            self.didBack?()
            return
        }
		// 「進む」場合の処理はここから
        super.didMove(toParent: parent)
    }
    
}