見出し画像

SwiftUIでいこう! - Combining Gestures(組合せ)

参考サイトです。

要するに組合せです。2つのジェスチャーを続けてやっていきます。その時に使うキーワードは

.sequenced

です。

実際のコードで見ていきます。まず2つの"@GestureState"のついた変数を作ります。

// For long press gesture
@GestureState private var isPressed = false

// For drag gesture
@GestureState private var dragOffset = CGSize.zero

この変数を使って、まずは

@GestureState private var isPressed = false

を使ったコード。

Image(systemName: "star.circle.fill")
.opacity(isPressed ? 0.5 : 1.0)
Image(systemName: "star.circle.fill")
.gesture(
 LongPressGesture(minimumDuration: 1.0)
  .updating($isPressed, body: { (currentState, state, transaction) in
  state = currentState
  })

続いて、

@GestureState private var dragOffset = CGSize.zero

を使ったコードです。

  .updating($dragOffset, body: { (value, state, transaction) in
  
   switch value {
    case .first(true):
     print("Tapping")
    case .second(true, let drag):
     state = drag?.translation ?? .zero
    default:
     break
}

このコードで"switch"で条件分けして動作を行います。詳細は

となりますが、

"LongPressGesture"()とDragGesture()を続けて動作させるので

.sequenced(before: DragGesture())

で、2つを紐付けます。連続して動作するようになります。長押しをまず行い、それに引き続きドラッグできるようになります。

全体のコードは

struct ContentView: View {
   // For long press gesture
   @GestureState private var isPressed = false
   // For drag gesture
   @GestureState private var dragOffset = CGSize.zero
   @State private var position = CGSize.zero
   var body: some View {
       Image(systemName: "star.circle.fill")
           .font(.system(size: 100))
           .opacity(isPressed ? 0.5 : 1.0)
           .offset(x: position.width + dragOffset.width, y: position.height + dragOffset.height)
           .animation(.easeInOut)
           .foregroundColor(.green)
           .gesture(
               LongPressGesture(minimumDuration: 1.0)
               .updating($isPressed, body: { (currentState, state, transaction) in
                   state = currentState
               })
               .sequenced(before: DragGesture())
               .updating($dragOffset, body: { (value, state, transaction) in
                   switch value {
                   case .first(true):
                       print("Tapping")
                   case .second(true, let drag):
                       state = drag?.translation ?? .zero
                   default:
                       break
                   }
               })
               .onEnded({ (value) in
                   guard case .second(true, let drag?) = value else {
                       return
                   }
                   self.position.height += drag.translation.height
                   self.position.width += drag.translation.width
       
               })
           )
   }


この記事が気に入ったらサポートをしてみませんか?