【SwiftUI】 simultaneousGesture で Drag 時に local 座標とglobal 座標両方使う

2021年1月28日

SwiftUI の DragGesture で view の移動をした際に、移動をさせつつ現在 drag している global な座標を取得したい場面がありました。その方法についてです。

simultaneousGesture

DragGesture の引数で coordinateSpace が指定できて何も指定しないと local で global も指定できます。

今回 local と global 両方の座標を使いたかったので最初普通に .gesture で二つの DragGesture を追加しようとしたのですが、最初に追加したものしか使えませんでした。そこで以下の様に simultaneousGesture で片方の DragGesture を追加したところ両方使用できました。

view に Gesture を追加する時 simultaneousGesture で追加すると複数同時に Gesture を行うことができます。

struct TestView4: View {
    @State var x: CGFloat = 200.0
    @State var y: CGFloat = 300.0
    
    @State var localTouchPositonX: CGFloat = 0.0
    @State var localTouchPositonY: CGFloat = 0.0
    
    @State var globalTouchPositonX: CGFloat = 0.0
    @State var globalTouchPositonY: CGFloat = 0.0
    
        var body: some View {
    
            VStack {
            
                
            Text("localTouchPostionX: \(localTouchPositonX)")
                .padding(.top, 30.0)
                
            Text("localTouchPostionY: \(localTouchPositonY)")
                
            Text("globalTouchPostionX: \(globalTouchPositonX)")
                .padding(.top, 30.0)
                
            Text("globalTouchPostionY: \(globalTouchPositonY)")
                
        
            Image("hoge")
                .aspectRatio(contentMode: .fit)
                .gesture(drag())
                .simultaneousGesture(dragGlobal())
                .position(x: x, y: y)
                        
            }
            
        }
    
      func drag() -> some Gesture {
        DragGesture(coordinateSpace: .local)
        .onChanged{ value in
            self.x += value.translation.width
            self.y += value.translation.height
            
            localTouchPositonX = value.location.x
            localTouchPositonY = value.location.y
        }
        .onEnded{ value in
            self.x += value.translation.width
            self.y += value.translation.height
            
            localTouchPositonX = value.location.x
            localTouchPositonY = value.location.y
        }
    }
    
    func dragGlobal() -> some Gesture {
      DragGesture(coordinateSpace: .global)
      .onChanged{ value in
        globalTouchPositonX = value.location.x
        globalTouchPositonY = value.location.y
      }
      .onEnded{ value in
        globalTouchPositonX = value.location.x
        globalTouchPositonY = value.location.y
      }
  }
}

デモ

以下の様に local の方は画像に対する座標なのでクリックしている場所が変わらないためほぼ変わりませんが global の方は root view に対する座標が取れています。

広告

SwiftUI 徹底入門 [ 金田 浩明 ]

価格:3,278円
(2020/11/18 22:49時点)
感想(0件)

詳細!SwiftUI iPhoneアプリ開発入門ノート iOS 13 Xcode 11対応【電子書籍】[ 大重美幸 ]

価格:2,970円
(2020/11/18 22:52時点)
感想(0件)