Help us understand the problem. What is going on with this article?

ViewControllerで戻るボタンのタップを検知する

More than 5 years have passed since last update.

ViewControllerによって自動で生成された戻るボタンをユーザーに押された時の処理を検知したいときに調べたメモ。みなさんもユーザーのログ関係でそういうことをしないといけない要件があったりするのではないかなと。

StackOverflowみるといくつか方法があった
http://stackoverflow.com/questions/5217992/back-button-callback-in-navigationcontroller-in-ios

3つ紹介しておく。

viewWillDisappear:時に判定

viewWillDisappear:時に自分自身がnavigationControllerのコンテナに追加されているかを判定することによって検出できる

- (void)viewWillDisappear:(BOOL)animated
{
    if (![self.navigationController.viewControllers containsObject:self]) {
        //戻るを押された
        NSLog(@"back");
    }

    [super viewWillDisappear:animated];
}

viewWillDisappear:はライフサイクルとして動作しているメソッドなので、戻るを押されてこのViewControllerがpopされた後に動作するためこの判定でも検知はできるが、下記のようなお約束の上で成り立っている

  • ViewControllerがpopされた
  • popされたから画面から消える
  • 画面から消えるからviewWillDisappear:が動作する
  • ViewControllerが破棄される

仕様上、popされた際に必ずviewWillDisappear:が起きるわけではなく、画面の表示が無くなった際に動作するので順番的には妥当っぽく見える。

上手く説明できないけど、ライフサイクルに依存するのは少し綱渡り的な気がするし人に教える時はこの方法はやめとくかな。

Appleのリファレンスを調べると、ライフサイクルを使う方法にはもうひとつやり方がある。それはisMovingFromParentViewControllerプロパティを調べるやり方で、このプロパティ自体の説明としても妥当な使い方をしている

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];

    if (self.isMovingFromParentViewController) {
        //親から削除されているかどうかなので戻るだけでなく閉じても判定
        NSLog(@"isMovingFromParentViewController");
    }

}

ただ、これは戻るボタンのタップ以外に、この親ViewControllerがモーダルの場合には「戻るボタン」だけでなく閉じても動作して同じように判定してしまう。

didMoveToParentViewController:で判断

didMoveToParentViewController:メソッドはコンテナがViewControllerを追加した後にその追加されたViewControllerで実行される。これを使えばpopされたとこを検知できるので戻るを判定できる(モーダルで閉じるにしても動作しない)。

//追加もしくは削除された後に動作する
- (void)didMoveToParentViewController:(UIViewController *)parent
{
    if (![parent isEqual:self.parentViewController]) {
        NSLog(@"back");
    }
}

最初self.parentViewControllerはnilだろうしnilかどうかで判断すればいいのでは...と思ったがこのメソッドの前に他のコンテナに追加されnilでないこともあるんだろう。

また、削除された時はdidMoveToParentViewController:の引数parent自体がnilのはずなのでparentがnilだったら削除されてると判断できなくもない気がする。より厳密さを求めて特定の親ViewControllerを比較したいためにisEqaul:メソッドで比較しているのだと思う(ただ戻るを押した際の動作的にはnilとnilの比較になっていた)。

didMoveToParentViewController:ってどんなんだっけとググったら昔書いた自分のメモがあった
http://qiita.com/yimajo/items/a5e16fa0f9c332a55ccf

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした