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)
}
}
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 DragGesture
s 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)
}
}