LoginSignup
0
0

More than 1 year has passed since last update.

UINavigationControllerのaccessibilityPerformEscape のデフォルト挙動まとめ

Posted at

先に結論

  • modalPresentationStyle = .pageSheetかつisModalInPresentation = falseの場合はスクラブジェスチャでモーダルをdismiss
  • それ以外(多分)はpopして、popするものがなくなったらaccessibilityPerformEscape()を見に行く。

accessibilityPerformEscape

そもそもaccessibilityPerformEscape()とは...

VoiceOverがオンのときに、二本指のスクラブジェスチャ(二本指でZを描くようなジェスチャ)によって、モーダル(もしくは階層)を閉じるためのメソッドであり、アクセシビリティ要素が特定の動作をサポートするためのメソッド群UIAccessibilityAction一つらしいです。

accessibilityPerformEscape()の中にスクラブジェスチャによって発火させたい処理(閉じる系以外の処理以外は書かない方が無難ですね)を書くと、スクラブジェスチャによって画面を閉じたり戻したりできます。

試しにVoiceOverを起動して適当なアプリ(SettingsとかSafariとか)を開いてスクラブジェスチャしてみると、popしたりdismissしたりします。

ドキュメント↓

UINavigationControllerにおけるスクラブジェスチャのデフォルト挙動

ところで、ドキュメントによるとaccessibilityPerformEscape()のデフォルト実装は戻り値としてfalseを返すようです。
この戻り値は、モーダルが正常に閉じられたかどうかなので、falseを返すということは中身は空ということじゃないのかなと思います。

なんですけど、UINavigationControllerは何も実装していなくても普通にスクラブジェスチャ効くんですよね、よくわからん。誰か詳しい人教えてください。

というわけで、accessibilityPerformEscape()をoverrideする上でUINavigationControllerのデフォルトの挙動に準じた動作をさせられるように、挙動を知っておくことは有意義だと思って色々触ってみたわけです。

試しに以下のような階層のアプリを作りました。
VC1, VC2, NavではそれぞれaccessibilityPerformEscape()をoverrideしてdismissするようにしています。

  • VC1
    • Nav
      • VC2
      • VC3

ここで、VC3を開いた状態からスクラブジェスチャを複数回行うことでNavのmodalPresentaitonStylemodalInPresentationを変更してそれぞれどんな挙動をするか、どのaccessibilityPerformEscapeが呼ばれるのかを確認してみました。

以下の表が結果です

modalPresentationStyle modalInPresentaion 挙動 呼ばれたaccessibilityPerformEscape()
.pageSheet true VC3 -> VC2 -> VC1 VC2 -> VC1 のタイミングで VC2のメソッドが呼ばれる
.pageSheet false VC3 -> VC1に遷移 -
.fullscreen
.formSheet
.popOver
true / false VC3 -> VC2 -> VC1 VC2 -> VC1 のタイミングで VC2のメソッドが呼ばれる

他にもmodalPresentationStyleは定義されていますが、.pageSheet以外変化ないので面倒になって確認していません。(誰か...)
多分同じということにしておきましょう!!

0
0
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
0
0