iOS16からonTapGetureで座標取得が可能になりました。
非常に便利なのでしっかり確認しておきましょう。
onTapGestureで座標を取得する
クロージャで座標を受け取れる様になりました。
これだけで座標の取得ができます。
@State var location = CGPoint()
.onTapGesture{ location in
self. location = location
}
デフォルトはローカル座標です。
グローバル座標を取得したい場合は引数を追加します。
coordinateSpaceという引数が追加されたのでglobalを指定するだけです。
.onTapGesture(coordinateSpace: .global) { location in
self. location = location
}
当然ですがcountと同時にも使用できます。
SpatialTapGesture
SpatialTapGestureという構造体が追加されています。
onTapGestureでこれを使っているというイメージです。
SpatialTapGesture()
.onEnded { event in
self.location = event.location
}
onEndedを使用します。
クロージャで受け取る値もそのまま座標ではありません。
メンバのlocationが持っているのでそちらから座標を取得してください。
別な場所に定義しておいてgesture modifierに渡す場合はこちらを使用します。
var gesture:some Gesture {
SpatialTapGesture().onEnded { event in
self.location = event.location
}
}
//gestureに渡す
.gesture(gesture)
iOS15までの場合は
SpatialTapGestureがありません、onTapGestureもこれを使っているはずなので当然未対応です。
しかしDragGestureには元から座標取得がありました。こちらを使って代用が可能です。
@State var point = CGPoint()
//
DragGesture(minimumDistance: 0)
.onEnded{ event in
self.location = event.location
//self.location = event.startLocation //開始位置も取れる
}
//gestureに入れるとこんな感じ
.gesture(DragGesture(minimumDistance: 0).onEnded{ event in
self.location = event.location
})
ポイントはminimumDistanceです。これを指定するとタップで反応する様になります。
また、手を離した位置を取得しています。
startLocationで開始位置も取得できますが、SpatialTapGestureはonEndedなので合わせました。
ただし、このままでは若干挙動が異なります。Dragしても反応してしまうからです。
Drag時は反応しない様に閾値を決めて、移動していない時のみ取得しましょう。
DragGesture(minimumDistance: 0)
.onEnded{ event in
if event.translation.width < 1 && event.translation.height < 1 { //実際はもっと大きい
location = event.location
}
}
DragGesture(minimumDistance: 0)
.onEnded{ event in
if point.location == event.startLocation { //移動が全くない場合
location = event.location
}
}
閾値は実際のSpatialTapGestureは結構動いても反応します。
時間で見ているのか距離で見ているのはわかりませんが10以上は動いても反応します。
ロングタップでも反応しますが、SpatialTapGestureもロングタップでもある程度反応するため、
おおよそ同じ挙動になったと考えてよいでしょう。
カウントに関しては考慮しません。
工夫する事で実現可能だとは思いますが今回はonTapGestureとSpatialTapGestureがメインなので、
そこまでは作っていません。
最後に
iOS16からSpatialTapGestureが実装されonTapGestureで座標取得が可能になりました。
以前より簡単に分かりやすく実装できる様になり、
カウントも使用できる為、ダブルタップやトリプルタップにも対応できます。
modifierで済み簡単に分岐できるので、互換を切らずiOS16ユーザー向けに追加も簡単だと思います。
ぜひ使ってみてください。
コメント