GestureにはViewをタップするだけでなくドラッグも認識してくれ、画像のドラッグも簡単にできます。
DragGesture
画像をドラッグさせるのはUIKitではtouchEventなどを使っていました
SwiftUIではDragGestureを使うことで可能となります。
Previewで画像をドラッグさせてみましょう。
DragGesture.Value
ViewのDragGestureを認識するために、Modifierから gesture(_:include:) を追加します。
Textの「Hello world!」を「Command」を押しながら選択
「Show SwiftUI Inspector…」からダイアログ下の「Add Modifier」に検索文字を入力してgestureを追加します
gesture は他のタップやロングプレスなども扱えますが
ここではDragGesture()を使います
1 2 3 4 5 6 7 8 9 10 11 12 13 |
struct ContentView: View { var body: some View { Text("Hello world!") .padding() .gesture( DragGesture() .onChanged(...) .onEnded(...) .updating(...) ) } } |
DragGestureのイニシャライズ:
1 2 3 4 |
init( minimumDistance: CGFloat, coordinateSpace: CoordinateSpace ) |
- minimumDistance:ドラッグを認識する範囲
- coordinateSpace:
- local:Viewの座標系
- grobal:画面の座標系
onChanged:
Gestureが変化したときに実行するアクションを追加
1 |
func onChanged((Value) -> Void) -> _ChangedGesture<DragGesture> |
onEnded:Gestureが終わった時のアクションを追加
1 |
func onEnded((Value) -> Void) -> _EndedGesture<DragGesture> |
updating: Gestureが変化したときにgesture state propertyをアップデートする、ただし値は保持されない
1 2 3 |
func updating<State>(_ state: GestureState<State>, body: @escaping (Value, inout State, inout Transaction) -> Void) -> GestureStateGesture<DragGesture, State> |
DragGesture.Value プロパティとして以下のものがあります
- var location: CGPoint
- 現在の場所
- var predictedEndLocation: CGPoint
- 現在の速度からの今止まった場合の最終位置の予測
- var predictedEndTranslation: CGSize
- 現在の速度からの今止まった場合の最終移動の予測
- var startLocation: CGPoint
- gestureの開始位置
- var time: Date
- 現在のドラッグイベントに関連付けられた時間
- var translation: CGSize
- ドラッグの開始から現在までの総移動合計
サンプルコード
適当な画像を1枚用意して(ここでは handbag@2x.png)
Assets.xcassetsに入れます。
画像のposition.x, position.yを初期化
onChanged と onEnded を使いクロージャーで
x, y の移動量の変化を画像の位置として設定します。
ContentView.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
import SwiftUI struct ContentView: View { @State var position: CGSize = CGSize(width: 200, height: 300) var drag: some Gesture { DragGesture() .onChanged{ value in self.position = CGSize( width: value.startLocation.x + value.translation.width, height: value.startLocation.y + value.translation.height ) } .onEnded{ value in self.position = CGSize( width: value.startLocation.x + value.translation.width, height: value.startLocation.y + value.translation.height ) } } var body: some View { VStack { Text("x: \(position.width)") Text("y: \(position.height)") Image("handbag") .position(x: position.width, y: position.height) .gesture(drag) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } |
画像がドラッグされます。
References:
Gestures | Apple Developer Documentation
DragGesture – SwiftUI | Apple Developer Documentation
DragGesture.Value – DragGesture | Apple Developer
CoordinateSpace – SwiftUI | Apple Developer Documentation
updating(_:body:) – DragGesture | Apple Developer
onEnded(_:) – Gesture | Apple Developer Documentation
onChanged(_:) – DragGesture | Apple Developer Documentation