[SwiftUI] Drag Gesture

RudinP·2025년 8월 19일
0

Study

목록 보기
341/352

주의

.onDrag 모디파이어는 드래그가 아닌 드래그 앤 드랍을 구현할 때 사용
드래그 제스처는 직접 만들어야 함.

1. 속성 구현

    var dragGesture: some Gesture {
        DragGesture()
            .onChanged { value in //드래그 인식 후 터치 움직이면 해당 클로저 반복 호출
                //새로운 상태가 value를 통해 전달됨
                
            }
            .onEnded { value in //드래그가 끝나면 호출. value에는 마지막 상태 저장
                
            }
    }
  • minimumDistance: 드래그로 인식되는 최소한의 이동 거리. 기본값 10(pt). 이 거리 이상으로 드래그 시 좌표가 반복적으로 전달됨.
  • coordinateSpace: 어떤 좌표체계를 사용할 지 전달.
    • .local: 제스처가 추가되어있는 뷰의 좌표 체계 (기본값)
    • .global: 전역 좌표체계.

2. 제스처 모디파이어 추가

.gesture(dragGesture)

3. (뷰 이동 시) offset modifier 추가

    var dragGesture: some Gesture {
        DragGesture()
            .onChanged { value in //드래그 인식 후 터치 움직이면 해당 클로저 반복 호출
                //새로운 상태가 value를 통해 전달됨
                currentTranslation = value.translation
            }
            .onEnded { value in //드래그가 끝나면 호출. value에는 마지막 상태 저장
                currentTranslation = .zero
                //드래그를 끝냈을 때 가장 마지막 거리 저장됨
                //이 상태에서 재 드래그 시 속성에 저장되어있는 거리만큼 offset 추가됨
                //터치 위치와 서클 위치가 어긋나게 됨을 방지키 위해 저장
                var t = finalTranslation
                t.width += value.translation.width
                t.height += value.translation.height
                finalTranslation = t
            }
    }
    
    @State private var currentTranslation = CGSize.zero
    @State private var finalTranslation = CGSize.zero //드래그 끝냈을 때 위치 보존 위한 속성
    
    var body: some View {
        VStack {
            Circle()
                .foregroundColor(.yellow)
                .frame(width: 100, height: 100)
                .offset(finalTranslation) //드래그 끝냈을 때 위치 보존 위함
                .offset(currentTranslation)
                .gesture(dragGesture)
                
        }
    }

순서

  • offset 모디파이어 다음에 gesture 모디파이어를 사용해야 한다.
  • 가능하다면 gesture 모디파이어는 마지막에 추가하는 것이 좋다.

GestureState

앞서 Translation을 저장하기 위해 State variable을 사용했다. 그러나, 이런 속성들은 GestureState로 선언 가능

  • GestureState 속성은 드래그가 끝나는 시점에 기본값으로 자동 초기화된다.
  • 대신 속성이 읽기전용이 된다.
    var dragGesture: some Gesture {
        DragGesture()
            .updating($currentTranslation, body: { value, state, transaction in
                //value: 제스처 상태
                //state: 입출력용. 바인딩 속성 전달
                //transaction: 제스처에 대한 부가정보, 보통 animation context
                state = value.translation
            })
            .onEnded { value in //드래그가 끝나면 호출. value에는 마지막 상태 저장
                //드래그를 끝냈을 때 가장 마지막 거리 저장됨
                //이 상태에서 재 드래그 시 속성에 저장되어있는 거리만큼 offset 추가됨
                //터치 위치와 서클 위치가 어긋나게 됨을 방지키 위해 저장
                var t = finalTranslation
                t.width += value.translation.width
                t.height += value.translation.height
                finalTranslation = t
            }
    }
    
    @GestureState private var currentTranslation = CGSize.zero
    @State private var finalTranslation = CGSize.zero //드래그 끝냈을 때 위치 보존 위한 속성
profile
iOS 개발자가 되기 위한 스터디룸...

0개의 댓글