SwiftUI:VStack/HStack/ZStack拖动手势无法工作

17
我不明白为什么在VStack/HStack/ZStack上无法使用DragGesture。请考虑以下简单示例:
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
            }
        )
    }
}

我希望整个视图可以根据拖动手势改变的offset变量上下移动。但是,即使我在VStack上写上.gesture修饰符,并且VStack占满了全屏(感谢.frame修饰符),拖动手势也无法在VStack上工作。只有当我拖动“Hello world”文本时,手势才起作用,但如果我在Text之外拖动(但仍然在全屏的VStack内),则不响应。有什么建议吗?谢谢。
2个回答

42

实际上,SwiftUI有一个旨在解决这个问题的功能,无需背景即可实现。

只需在手势修饰符之前放置.contentShape(Rectangle()),它将响应整个包围矩形。 :)


1
抱歉,我在代码中发现了一个错误 - 我错误地称呼了一个自定义结构体为 DragGesture。您的建议很好用。 - Niko Gamulin
2
请注意正确的顺序很重要:必须在调用.contentShape之前调用.frame,否则它将无法正常工作。 - robinst
太棒了!这是一个非常简单的修复。 - yspreen

7
您的容器是透明的。透明的东西无法处理事件。因此,请添加一些背景,就像下面的演示中一样,所有功能都可以正常使用。
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
        }
    )
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接