심플
.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 는 프로퍼티로 어떤 동작을 수행할지, 그리고 눌러지는 동작 동안 어떤 걸 수행할지 정해줄 수 있음!
줌인 줌아웃 제스쳐
이런 식으로 추가해줄 수 있음
근데 이렇게만 추가했을 때 한가지 문제가 있는데
줌 인한 뒤에 터치에서 손을 떼고, 다시 줌 제스쳐를 실행하면 다시 처음부터 크기를 조절하게 됨
수정해보자
lastAmount 항목을 추가해서 제스쳐가 끝날 때 현재의 밸류를 저장할 수 있게 해주자
많이 쓰지는 않지만 알아놓자
참 이런 제스쳐효과들은 프리뷰에서 바로 확인하기 힘들어서 시뮬레이터로 확인해보는 게 좋음
(예전엔 이랬던 거 같은데 지금은 프리뷰에서도 잘 된다)
이전의 제스쳐들 구현보다는 살짝은 복잡함
또 그만큼 중요하기도함
활용방법은 틴더처럼 스와이프 하는 거?!
이렇게 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 에서 잠깐 헤맸는데
현재 위로 올리는 드래그 행동 자체는 오프셋 값이 -로 커짐
이거만 인지해두기