I don't understand why the DragGesture
doesn't work on VStack/HStack/ZStack. Consider the following simple example:
struct ContentView: View {
@State private var offset = CGSize.zero
var body: some View {
VStack {
Text("Hello World!")
}
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
.edgesIgnoringSafeArea(.all)
.offset(y: offset.height)
.gesture(DragGesture()
.onChanged { val in
self.offset = val.translation
}
.onEnded { val in
self.offset = .zero
}
)
}
}
I'd like the whole view to move up and down based on the offset
var (changed by the drag gesture). But even if I write the .gesture
modifier on the VStack
and even if the VStack
is full screen (thanks to the .frame
modifier) the drag gesture won't work on the VStack
. The gesture works only if I drag the "Hello world" text, but it's unresponsive if I drag outside the Text
(but still inside the full screen VStack
). Any ideas? Thanks.
The HStack is used to stack views horizontally. Just like the VStack, you can set the alignment and space items. By default, stacks in SwiftUI will take the minimum space and align to the center. The Spacer is essential for pushing the content to use the maximum space.
You can use 3 kinds of stacks with SwiftUI: VStack, a vertical stack, which shows views in a top-to-bottom list HStack, a horizontal stack, which shows views in a left-to-right list ZStack, a depth-based stack, which shows views in a back-to-front list
You might consider using a ZStack if you were to have an image with some dynamic text in front of it. With HStack organising views within its view, this also means that we can embed a stack within a stack and create more complex views.
VStack, a vertical stack, which shows views in a top-to-bottom list HStack, a horizontal stack, which shows views in a left-to-right list ZStack, a depth-based stack, which shows views in a back-to-front list You can combine these stacks to build a complex layout much easier.
Actually, there's a SwiftUI feature meant to address just that issue with no need for a background.
Simply place .contentShape(Rectangle())
just before your gesture modifier and it will respond to the whole enclosing rectangle. :)
Your container is transparent. Transparent thing does not handle events. So, add some background, like in demo below and all works.
var body: some View {
VStack {
Text("Hello World!")
}
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
.edgesIgnoringSafeArea(.all)
.background(Color.white)
.offset(y: offset.height)
.gesture(DragGesture()
.onChanged { val in
self.offset = val.translation
}
.onEnded { val in
self.offset = .zero
}
)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With