[SwiftUI Bootcamp] Intermediate

Woozoo·2023년 1월 21일
0

[SwiftUI]

목록 보기
16/26

.onLongPressGesture()

심플
.onLongPressGesture 추가해주면 됩니다


이렇게 프로퍼티 추가도 가능

maximumDistance는 터치하고 얼마나 포인트를 움직일 수 있게 해줄건지임

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

onLongPressGesture 는 프로퍼티로 어떤 동작을 수행할지, 그리고 눌러지는 동작 동안 어떤 걸 수행할지 정해줄 수 있음!


MaginificationGesture

줌인 줌아웃 제스쳐


이런 식으로 추가해줄 수 있음
근데 이렇게만 추가했을 때 한가지 문제가 있는데
줌 인한 뒤에 터치에서 손을 떼고, 다시 줌 제스쳐를 실행하면 다시 처음부터 크기를 조절하게 됨
수정해보자


lastAmount 항목을 추가해서 제스쳐가 끝날 때 현재의 밸류를 저장할 수 있게 해주자

요런식으로 인스타 피드 느낌도 구현 가능


RotationGesture()

많이 쓰지는 않지만 알아놓자

참 이런 제스쳐효과들은 프리뷰에서 바로 확인하기 힘들어서 시뮬레이터로 확인해보는 게 좋음
(예전엔 이랬던 거 같은데 지금은 프리뷰에서도 잘 된다)


DragGesture()

이전의 제스쳐들 구현보다는 살짝은 복잡함
또 그만큼 중요하기도함

활용방법은 틴더처럼 스와이프 하는 거?!

이렇게 offset을 밸류 값이 changed 될 때 변경시켜주고
변경이 끝나면 다시 원래의 자리로 돌아오게 해줄 수 있음

틴더처럼 만들어보자


scaleEffect를 추가하고 현재의 스크린의 크기에 따른 반응현 scale을 만들어줌
(여기서 abs는 절대값으로 표현하는 키워드임)
(min은 x,y 중에 더 작은 숫자를 리턴함)

로테이션도 추가해보자


signUp 뷰도 만들 수 있음

struct DragGestureBootcamp2: View {
    
    @State var startingOffsetY: CGFloat = UIScreen.main.bounds.height * 0.85
    @State var currentDragOffsetY: CGFloat = 0
    @State var endingOffsetY: CGFloat = 0
    
    var body: some View {
        ZStack {
            Color.green.ignoresSafeArea()
            
            MySignUpView()
                .offset(y: startingOffsetY)
                .offset(y: currentDragOffsetY)
                .offset(y: endingOffsetY)
                .gesture(
                    DragGesture()
                        .onChanged { value in
                            withAnimation(.spring()) {
                                currentDragOffsetY = value.translation.height
                            }
                        }
                        .onEnded { value in
                            withAnimation(.spring()) {
                                if currentDragOffsetY < -150 {
                                    endingOffsetY = -startingOffsetY
                                } else if endingOffsetY != 0 && currentDragOffsetY > 150 {
                                    endingOffsetY = 0
                                }
                                currentDragOffsetY = 0
                            }
                        }
                )
            
            Text("\(currentDragOffsetY)")
        }
        .ignoresSafeArea(edges: .bottom)
    }
}

struct MySignUpView: View {
    var body: some View {
        VStack(spacing: 20) {
            Image(systemName: "chevron.up")
                .padding(.top)
            Text("Sign up")
                .font(.headline)
                .fontWeight(.semibold)
            
            Image(systemName: "flame.fill")
                .resizable()
                .scaledToFit()
                .frame(width: 100, height: 100)
            
            Text("This is the description for our app. This is my Favorite SwiftUI course and I recommend to all of my friends to subscribe to Swiftful Thinking")
                .multilineTextAlignment(.center)
            
            Text("Create an account".uppercased())
                .foregroundColor(.white)
                .font(.headline)
                .padding()
                .padding(.horizontal)
                .background(Color.black.cornerRadius(10))
            Spacer()
        }
        .frame(maxWidth: .infinity)
        .background(Color.white).cornerRadius(30)
    }
}

struct DragGestureBootcamp2_Previews: PreviewProvider {
    static var previews: some View {
        DragGestureBootcamp2()
    }
}

중점적으로 볼건 offset부분
if currentOffsetY < -150 에서 잠깐 헤맸는데
현재 위로 올리는 드래그 행동 자체는 오프셋 값이 -로 커짐
이거만 인지해두기

profile
우주형

0개의 댓글