[SwiftUI] LongPressGesture

Junyoung Park·2022년 8월 18일
0

SwiftUI

목록 보기
1/136
post-thumbnail
post-custom-banner

How to use LongPressGesture in SwiftUI | Continued Learning #1

LongPressGesture

  • 일반적인 탭 제스처와 달리 특정 오브젝트를 누르는 시간, 오브젝트를 누른 채 손가락을 어느 정도 거리로 떨어뜨려도 기능을 작동할지 설정 가능한 제스처

구현 목표

  • Click Here을 눌렀을 때 파란색 바가 차오르도록 한다.
  • Reset을 눌렀을 때 다시 원래 상태로 돌아가도록 한다.

구현 태스크

  1. 파란 색 바가 가득 찬 상태 = 성공 상태 = Click Here을 누르고 있어야 하는 시간
  2. 파란 색 바를 누르기 '시작', 즉 터치 감지 시작부터 확인해야 함. 도중 터치가 실패한다면 다시 원상복구
  3. 회색 상태 → 파란 바 업데이트 / 파란 상태 → 회색 바 업데이트 양방향 설계
  4. isCompleted를 통해 2번, isSuccess를 통해 1번 목표

핵심 코드

.onLongPressGesture(minimumDuration: 1.0, maximumDistance: 50) { isPressing in
                    // press start -> min duration
                    } perform: {
                    // 구현할 동작
                    }

소스 코드

import SwiftUI

struct LongPressGestureBootCamp: View {
    @State private var isCompleted: Bool = false
    @State private var isSuccess: Bool = false
    var body: some View {
        VStack {
            Rectangle()
                .fill(.blue)
                .frame(maxWidth: isCompleted ? .infinity : 0)
                .frame(height: 55)
                .frame(maxWidth: .infinity, alignment: .leading)
                .background(.gray)
            HStack {
                Text("Click Here")
                    .foregroundColor(.white)
                    .padding()
                    .background(.black)
                    .cornerRadius(10)
                    .onLongPressGesture(minimumDuration: 1.0, maximumDistance: 50) { isPressing in
                        // press start -> min duration
                        if isPressing {
                            withAnimation(.easeInOut(duration: 1.0)) {
                                isCompleted.toggle()
                            }
                        } else {
                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                                if !isSuccess {
                                    withAnimation(.easeInOut) {
                                        isCompleted = false
                                    }
                                }
                            }
                        }
                    } perform: {
                        withAnimation(.easeInOut) {
                            isSuccess = true
                        }
                    }
                Text("Reset")
                    .foregroundColor(.white)
                    .padding()
                    .background(.black)
                    .cornerRadius(10)
                    .onTapGesture {
                        isCompleted = false
                        isSuccess = false
                    }
            }
        }
    }
}

구현 화면

profile
JUST DO IT
post-custom-banner

0개의 댓글