I have created a bottom card with a drag gesture that is not yet finished. But I ran into an issue when I set the default translation height from zero and it just jumps to what I think is translation 0.
import SwiftUI
struct TimetableBottomCardView: View {
@State var translation: CGSize = CGSize(width: .zero, height: 785)
var body: some View {
VStack {
TimetableBottomCardUI()
Spacer()
}.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Material.ultraThick)
.mask(RoundedRectangle(cornerRadius: 35).ignoresSafeArea(.all, edges: .bottom))
.offset(y: translation.height)
.gesture(
DragGesture()
.onChanged { value in
translation = value.translation
}
.onEnded { value in
withAnimation {
let DefaultTranslation: CGSize = CGSize(width: .zero, height: 785)
translation = DefaultTranslation
}
}
)
}
}
struct TimetableBottomCardView_Previews: PreviewProvider {
static var previews: some View {
TimetableBottomCardView()
.background(.blue)
}
}
CodePudding user response:
You are assigning your transition value when your DragGesture changes. When you use onChanged, its value gives you a relative position, rather than an absolute one. That means your transition value only changes depending on where your last touch appeared, so as you're offsetting your view by 785, when onChanged gets triggered your view jumps up due to DragGestures relative value.
As you can see here, your offset was 785, but when onChanged gets triggered, it sets it to 0, which means, it also sets its offset to zero
To avoid this behavior, you have to add your offset amount (785) to your card so that you can save your previous offset.
Result:
Code:
import SwiftUI
struct TimetableBottomCardView: View {
@State var translation: CGSize = CGSize(width: .zero, height: 785)
var body: some View {
VStack {
Text("Draggable Card")
.frame(width: 300, height: 300)
.background(.teal)
Spacer()
}.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Material.ultraThick)
.mask(RoundedRectangle(cornerRadius: 35).ignoresSafeArea(.all, edges: .bottom))
.offset(y: translation.height)
.gesture(
DragGesture()
.onChanged { value in
print(value.translation)
translation = CGSize(width: value.translation.width, height: value.translation.height 785)
}
.onEnded { value in
withAnimation {
let DefaultTranslation: CGSize = CGSize(width: .zero, height: 785)
translation = DefaultTranslation
}
}
)
.onChange(of: translation) {_ in
// print(translation)
}
}
}
struct TimetableBottomCardView_Previews: PreviewProvider {
static var previews: some View {
TimetableBottomCardView()
.background(.blue)
}
}


