🔭

【SwiftUI】GestureMask 観測隊

2024/12/04に公開

この記事は、ユーザーの操作にどう対応するかを決める GestureMask を観測する。

環境

Sequoia 15.1
Xcode 16.1

シミュレータ

  • iPhone13 iOS15.5
  • iPhone14 iOS16.4
  • iPhone15 iOS17.5
  • iPhone16 iOS18.1

観測コード

import SwiftUI

struct A: View {
    var body: some View {
        VStack {
            B()
            Text("Hello, world!")
        }
        .gesture(TapGesture().onEnded({ _ in
            print("A")
        }), including: .gesture) //⭐️ここを切り替える
    }
}

struct B: View {
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(.tint)
            
        }
        .gesture(TapGesture().onEnded({ _ in
            print("B")
        }))
    }
}

反応を観測するところ

including: の引数を切り替えて

  • Bのエリア内
  • Aのエリア内、かつ、Bのエリア外

を観測する。

反応がありえるところは表にすると

子(B)のエリア 子のエリアの外
親が反応
子が反応 -

となる。

.all

Enable both the added gesture as well as all other gestures on the view and its subviews.

子(B)のエリア 子のエリアの外
親が反応 -
子が反応 -

.gesture

Enable the added gesture but disable all gestures in the subview hierarchy.

iOS15.5 iOS16.4 iOS17.5

子(B)のエリア 子のエリアの外
親が反応
子が反応 - -

iOS18.1

子(B)のエリア 子のエリアの外
親が反応 -
子が反応 -

.subviews

Enable all gestures in the subview hierarchy but disable the added gesture.

子(B)のエリア 子のエリアの外
親が反応 - -
子が反応 -

.none

Disable all gestures in the subview hierarchy, including the added gesture.

iOS15.5 iOS16.4 iOS17.5

子(B)のエリア 子のエリアの外
親が反応 - -
子が反応 - -

iOS18.1

子(B)のエリア 子のエリアの外
親が反応 - -
子が反応 -

感想

説明の文章と違うなという印象があります。今後も変更されるかもしれません。

勝手な予想

勝手な予想ですが、5つあるといいかも

.all

子のエリア 子のエリアの外
親が反応
子が反応 -

不自然にならないように注意。
親と子の反応の内容の性質が違うときなどに必要になることがあるかも。

親総取り

子のエリア 子のエリアの外
親が反応
子が反応 - -

子は無効にして親が総取り。

subview優先

子のエリア 子のエリアの外
親が反応 -
子が反応 -

子の操作が重要なので優先する。親はその他のエリアで反応する。

subviewのみ

子のエリア 子のエリアの外
親が反応 - -
子が反応 -

親は無効にする。が子の操作は必要不可欠。
親のジェスチャーは定義しておくが、状況によって親のジェスチャーを無効にするときにこれに切り替える。

.none

子のエリア 子のエリアの外
親が反応 - -
子が反応 - -

状況によってエリア全体を無効にするときにこれに切り替える。

行動

昨年、フィードバックアシスタントでAppleに5パターン案を提案しました。

Discussion