👋
【SwiftUI】.gestureについて
SwiftUI のジェスチャ操作についてです。
SwiftUI では、.gesture
修飾子を使ってビューにジェスチャを追加することができます。
以下のコードでは、四角形ビューにタップジェスチャを追加しています。
Rectangle()
.foregroundColor(.red)
.frame(width: 250, height: 350)
.gesture( ここにジェスチャを定義する )
ジェスチャでは、3つのイベントハンドラがあります。
- onEnded:イベントが終了した際に処理。
- onChanged:ジェスチャの値が変わった際に処理。
- updating:ジェスチャの値が変わるたびにジェスチャの状態を更新。
タップ
タップのジェスチャでは TapGesture
を使用し、タップ終了時のイベントハンドラを定義します。
Rectangle()
.foregroundColor(.red)
.frame(width: 250, height: 350)
.gesture(tapGesture)
var tapGesture: some Gesture {
TapGesture()
.onEnded {
// タップ後の処理
}
}
TapGesture
のcount
パタメータを使用すると、指定した数の連続タップでジェクチャを起動することができます。
var tapGesture: some Gesture {
TapGesture(count: 2) // 2回連続タップでジェスチャ起動
.onEnded {
// タップ後の処理
}
}
連続タップにする場合は、2回が限度かなと思っています。
3回以上のタップだと使い勝手が悪くなってしまいますので、気をつけましょう。
長押し
長押しのジェスチャではLongPressGesture
を使用します。
Rectangle()
.foregroundColor(.red)
.frame(width: 250, height: 350)
.gesture(longPressGesture)
var longPressGesture: some Gesture {
LongPressGesture()
.onEnded {
// 長押し後の処理
}
}
LongPressGesture
のminimumDuration
パラメータの設定で、長押しの時間を指定することができます。
なにも指定しない場合は、デフォルトで 0.5 秒が設定されます。
var longPressGesture: some Gesture {
LongPressGesture(minimumDuration: 1.0) { // 1秒後に動作
.onEnded {
// 長押し後の処理
}
}
}
ドラッグ
ドラッグのジェスチャではDragGesture
を使用します。
var dragGesture: some Gesture {
DragGesture() {
.onChanged { value in
// ドラッグ中の処理
}
.onEnded { value in
// ドラッグ終了時の処理
}
}
}
以下のコードはオブジェクトをドラッグして移動させる処理です。
struct DragView: View {
// 移動されるオブジェクトのサイズ
@State private let circleSize: CGFloat = 100
// オブジェクトの位置
@State private var offset: CGSize = CGSize.zero
var dragGesture: some Gesture {
DragGesture() {
.onChanged { value in
// 位置を更新
offset = CGSize(width: value.startLocation.x + value.translation.width - circleSize/2,
height: value.startLocation.y + value.translation.height - circleSize/2)
}
}
}
var body: some View {
VStack {
Spacer()
Circle()
.frame(width: circleSize, height: circleSize)
.offset(offset)
.gesture(dragGesture) // ドラッグジェスチャー
Spacer()
}
}
}
以下の箇所で Circle オブジェクトの位置を更新させています。
offset = CGSize(width: value.startLocation.x + value.translation.width - circleSize/2,
height: value.startLocation.y + value.translation.height - circleSize/2)
- startLocation:ドラッグ開始位置を取得。
- translation :ドラッグ開始位置から現在位置までの距離を取得。
まとめ
- TapGesture: タップ
- LongPressGesture: 長押し
- DragGesture: ドラッグ
Discussion