LoginSignup
2
0

More than 3 years have passed since last update.

FlutterのiOSアプリで、端末のエッジ部分の onTapDown が遅延する

Posted at

経緯

とあるアプリの開発で、ユーザのタップ操作に即座に反応する必要があり、画面の左右にボタン領域を用意して、 onTapDown でイベントをハンドリングしようとしました。
iOS simulatorで確認しているところでは上手く動いていたのですが、iPhone XRなどの実機で確認してもらうと、「画面を押した瞬間に反応せず、コンマ数秒経ってから反応しているように見える」という指摘があり、調査しました。

状況としては、以下の動画のようなイメージです。

d0fme-7zyqw.gif

最初の2タップは、比較的中央寄りをタップしているので、指が触れた瞬間ぐらいでテキストの行が増えています。
次の2タップは、意図的に画面端をタップしており、タップした瞬間から500msecぐらい遅れて行が増えています。

調査していくと、iOSのOS側の制御として「エッジに触れられたときには、OSのジェスチャーかもしれないから、アプリにイベントを渡すのは少し待つ」的な動作がありそうでした。

そして、iOSの preferredScreenEdgesDeferringSystemGestures にて [.left, .right] を返せば良さそう、、、という記事も発見したのですが、今回の開発ではFlutterを利用していたため、UIViewControllerが露出しておらず、継承してそれを利用する方法がわかりませんでした。

解決策

調べていくと、Flutterで利用されている UIViewController は、 FlutterViewController ということがわかりました。

また、同僚からのアドバイスで、 extension を使ってみました。

結果としては、 {project dir}/ios/Runner/AppDelegate.swift の末尾に、以下の記述を追加することで改善しました。

public extension FlutterViewController {
    override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge {
        return [.left, .right]
    }
}

改善後の動画です。

59v1n-f7upv.gif

こちらも、上の動画と同様に、最初の2タップは中央寄り、次の2タップは端をタップしていますが、どちらもタップした瞬間に反応しています。

その他

同じように、 preferredScreenEdgesDeferringSystemGestures にて [.bottom] を返すと、1度はホーム画面への遷移を防げます。

5jlyk-lvypl.gif

一般的なアプリで実装されているとただ迷惑ですが、ガチャガチャ操作するようなゲームなどでは、この指定をしても良いかもしれませんね。

その他2

多くのアプリでは、こういった制御が必要になったとしても、特定の画面のみかと思います。
Flutterパッケージを作成し、 preferredScreenEdgesDeferringSystemGestures が返す値を変数化、Flutterアプリ側からの呼び出しでその変数を書き換え、 setNeedsUpdateOfScreenEdgesDeferringSystemGestures を呼び出してやる、、、というのが良さそうではあります。

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