So, I saw many swipe to buy buttons around the web and on many apps. I thought it would be good to implement onto my app. But for some reason, the ZStack isn't functioning properly, the background is on top of the swipe arrow. I can't properly place it inside of another view. Furthermore, how would one perform an action when the swipable arrow is fully at the end?
import SwiftUI
struct ContentView: View {
@State var viewState = CGSize(width: 0, height: 50)
var body: some View {
ZStack{
/// This part is the background of the swipe to buy
RoundedRectangle(cornerRadius: 10)
.offset(x: viewState.width)
.frame(width: 800,height: 100)
HStack{
// This part is the actual swiping arrow
ZStack {
RoundedRectangle(cornerRadius: 30)
.fill(Color.blue)
.frame(width: 100, height: 100)
.offset(x: viewState.width)
.gesture(
DragGesture().onChanged { value in
viewState = value.translation
}
.onEnded { value in
withAnimation(.spring()) {
viewState = .zero
}
}
)
Image(systemName: "chevron.right")
.offset(x: viewState.width)
.gesture(
DragGesture().onChanged { value in
viewState = value.translation
}
.onEnded { value in
withAnimation(.spring()) {
viewState = .zero
}
}
)
}
Spacer()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
'''
CodePudding user response:
Your ZStack is working fine, the issue is you are giving the top RoundedRectangle fix width = 800 and you use Spacer() to push the HStack to the leading side. You have to remove this width in order to work this fine, like this:
RoundedRectangle(cornerRadius: 10)
.offset(x: viewState.width)
.frame(width: 800, height: 100)
But if you want fix width you can use background() instead of ZStack, like this:
HStack{
ZStack {
RoundedRectangle(cornerRadius: 30)
.fill(Color.blue)
.frame(width: 100, height: 100)
.offset(x: viewState.width)
.gesture(
DragGesture().onChanged { value in
viewState = value.translation
}
.onEnded { value in
withAnimation(.spring()) {
viewState = .zero
}
}
)
Image(systemName: "chevron.right")
.offset(x: viewState.width)
.gesture(
DragGesture().onChanged { value in
viewState = value.translation
}
.onEnded { value in
withAnimation(.spring()) {
viewState = .zero
}
}
)
}
Spacer()
}.background(
RoundedRectangle(cornerRadius: 10)
.offset(x: viewState.width)
.frame(width: 800,height: 100)
)