blog icon indicating copy to clipboard operation
blog copied to clipboard

How to drag using DragGesture in SwiftUI

Open onmyway133 opened this issue 2 years ago • 0 comments

Change element position using either offset or position, and use DragGesture

Use GestureState to store the updating startDragLocation to keep the start location when drag begins, so we can add translation

struct MoveModifier: ViewModifier {
    @Binding var position: CGPoint

    @GestureState private var startLocation: CGPoint?
    
    func body(content: Content) -> some View {
        content
            .gesture(gesture)
    }
    
    private var gesture: some Gesture {
        DragGesture()
            .onChanged { value in
                var position = startLocation ?? position
                position.x += value.translation.width
                position.y += value.translation.height
                self.position = position
            }
            .updating($startLocation) { (value, gestureState, transaction) in
                gestureState = gestureState ?? position
                transaction.animation = .easeInOut
            }
            .onEnded { _ in
                // No op
            }
    }
}

struct CanvasView: View {
    @GestureState private var startDragLocation: CGPoint?

    private var elementsView: some View {
        ForEach($viewModel.elements) { $element in
            ElementView(
                element: $element
            )
            .offset(x: element.position.x, y: element.position.y)
            // .position(element.position)
            .onTapGesture {
                // on tap
            }
            .modifier(MoveModifier(position: $element.position))
        }
    }
}

Read more

  • https://developer.apple.com/documentation/swiftui/making-fine-adjustments-to-a-view-s-position
  • https://developer.apple.com/documentation/swiftui/adding-interactivity-with-gestures

onmyway133 avatar Jul 28 '22 21:07 onmyway133