Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI: VStack/HStack/ZStack drag gesture not working

Tags:

ios

swift

swiftui

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.

like image 524
matteopuc Avatar asked Nov 23 '19 13:11

matteopuc


People also ask

What is the difference between hstack and vstack in SwiftUI?

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.

What are the different types of stacks in SwiftUI?

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

What is the difference between hstack and zstack?

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.

What is the difference between hstack and vstack in Revit?

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.


2 Answers

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. :)

like image 103
Anton Avatar answered Oct 16 '22 14:10

Anton


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
        }
    )
}
like image 7
Asperi Avatar answered Oct 16 '22 13:10

Asperi