ソースコード
単純化したもの
ZStack {
//Circle1
Circle()
.frame(width: 15.0, height: 15.0)
.position(x: 100.0, y: 100.0)
.gesture(
DragGesture()
.onChanged { value in
print("Circle1", value.location)
}
)
//Circle2
Circle()
.frame(width: 15.0, height: 15.0)
.position(x: 200.0, y: 200.0)
.gesture(
DragGesture()
.onChanged { value in
print("Circle2", value.location)
}
)
//子ビューのジェスチャ
}
.contentShape(Rectangle())
.gesture(
DragGesture()
.onChanged { value in
print("ZStack", value.location)
}
)
//親ビューのジェスチャ
この例の場合、子ビューのCircle1,2をドラッグした時はCircle1:やCircle2:の後に座標が出力され、Circleのない場所をドラッグした時はZStack: の後に座標が出力される。つまり、子ビューがある場所では子ビューのジェスチャが有効になり、それ以外の場所では親ビューのジェスチャが有効になる。子ビューには.position
モディファイアをつけることに注意する。もし付けなかった場合、親ビューのZStackのジェスチャが効かなくなる。ただし、Circle1,2どちらかにpositionモディファイアがついていれば良い。試しに、position(...)をコメントアウトして実験してみるとわかりやすいだろう。
GestureMaskについて
GestureMaskを、SwiftUIの.gestureモディファイアの2番目の引数including: に与える。
→AppleDeveloper Documentation
上記の例と直接の関係はないが、GestureMaskの親子ビューのジェスチャの優先の仕組みから、ZStackに直接ジェスチャをつけるというこの実装を思いついた。
GestureMaskについての詳細は以下の記事をどうぞ。
[SwiftUI]Gestureを知る!
SwiftUIのGestureMaskに別の世界線はあるか