1
1

More than 3 years have passed since last update.

記事概要

「戻るボタンをタップした時に○○する」という戻る以外の処理を挟むという仕様を実現する際のアプローチの整理。

  • やりがちNGパターン
  • 一部対応パターン
  • 一括対応パターン(UINavigationController単位)
  • まとめ

やりがちNGパターン

backBarButtonItemのactionは無視されるため動作しません。

navigationItem.backBarButtonItem = UIBarButtonItem(title: "戻る", style: .plain, target: nil, action: #selector(doSomething))

@objc
func doSomething() {
    // 戻るボタンの動作処理
}

一部対応パターン

navigationItemのleftBarButtonItemを利用する

この方法はかなりネット上に広がってる方法です。

一部対応.swift
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "戻る", style: .plain, target: nil, action: #selector(doSomething))

@objc
func doSomething() {
    // 戻るボタンの動作処理
}

良い点

  • UIViewControllerから指定もできるので、見通しが良い。

問題点

  • backBarButtonItemとleftBarButtonItemでボタン位置が若干変わる
  • (iOS7の時のような)HIGのガイドラインが変わるような変更があった場合、実装箇所において各画面で修正が必要。

一括対応パターン(UINavigationController単位)

UINavigationControllerのサブクラスを実装し、UINavigationBarDelegateを採用する

UINavigationController.navigationBarUINavigationBarDelegate直接手動で設定できません。(実行時エラーになります)
また、UINavigationController.navigationBarget-onlyなので以下に実装になります。

final class OriginalNavigationController: UINavigationController, UINavigationBarDelegate {
    func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        // 戻るボタンの動作処理
        return false
    }
}

良い点

  • 一括で対応できるので、共通仕様として実装する場合はシンプルに実現できる。

問題点

  • 特定の1画面に対してだと、少し大袈裟な実装。
  • 特定の条件の画面に対してだと、画面特定が泥臭い感じになり、拡張時に考慮する必要がある。
  • UIViewControllerから離れているので、どこで制御しているか分かりにくい。(半年後忘れているかも?)
  • UIViewControllerに関連するロジックを実装する必要がある場合も設計上問題が出がち。

まとめ

今回提示したアイデアとしては2つですが、一長一短なので状況に応じて対応かなと思います。
個人的にはiOS7の時にデザイン修正がちょっとした作業量になった経験から、前者を実装するのであれば特定の条件の画面のみ戻るボタンで実現するというアプローチ以外に機能実現する方法を検討し、回避するのも手だと考えています。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1