Iganinのブログ

日頃の開発で学んだ知見を中心に記事を書いています。

【SwiftUI】BackButtonの文字を消す

語り尽くされている感があるが、今一度調べたので備忘録的にメモ。

tl;dr;

  • UINavigationBarのAppearnceをいじることで達成可能
  • navigationBarBackButtonHiddenにして、navigationItemをnavigationBarLeadingに追加でも対応できるが以下の機能が消える
    • SwipeGestureによる元の画面への遷移
    • 戻るボタン長押しによるStackの表示と選択による画面遷移

環境

以下の環境で確認

UIKit

まずUIKitの場合にどうするかを記述する。 これは非常に簡単に行うことができて、navigationItem.backButtonDisplayModeminimalにしてやれば良い。 iOS 14以上の制約はあるが、昨今は基本的にはこのサポートバージョンの条件を満たしていると思う。 backButtonDisplayMode | Apple Developer Documentation

SwiftUI

SwiftUIでどうするかを記述する。

UINavigationBarのAppearanceをいじる

おそらくこの方法が筋が良いと思う。 以下のようにすることで、BackButtonのテキストを非表示にすることができる。

appearance.backButtonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.clear]

この方法であれば、後述の方法では無効化されてしまうデフォルトの以下の機能も無効化されない。

  • Swipe Gestureによる画面遷移
  • 長時間押下によるStackの表示 + 指定した画面への遷移

ToolbarItem(placement: .navigationBarLeading)

navigationBarBackButtonHidden()でBackButtonを非表示にして、ToolbarItem(placement: .navigationBarLeading) で独自の戻るボタンを置く方法。 以下のようにViewModifierを作成すると設定がだいぶ楽になる。

struct MinimalNavigationBarBackButton: ViewModifier {
  @Environment(\.dismiss) var dismiss

  public func body(content: Content) -> some View {
    content
      .navigationBarBackButtonHidden(true)
      .toolbar {
        ToolbarItem(placement: .navigationBarLeading) {
            Button {
                dismiss()
            } label: {
                Image(systemName: "chevron.backward")
            }
            .foregroundStyle(Color.black)
        }
      }
  }
}

直感的な方法ではあるが、デフォルトである以下の機能が無効になる。

  • A Swipeによる元の画面への画面遷移
  • B 戻るボタンの長時間押下によるStackの表示 + 指定Stackへの遷移

AについてはUINavigationControllerをいじることで実装できるが、全体に適用するとBackButtonがHiddenでもSwipeで戻れてしまうので制御が必要。 Bもおそらく実装できるが手間はかかりそう。

extension UINavigationController: UIGestureRecognizerDelegate {
    override open func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = self
    }

    public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return viewControllers.count > 1
    }
}

その他

以下の方法も検討できるが、BackButton以外の挙動が変わりそうなのでその辺りの考慮が必要そう。

  • 画面遷移と同時にUserのnavigationTitleを空文字にする
  • toolbarRoleにeditorを指定

Reference