SwiftUI DragGesture仅在一个方向上

时间:2019-10-04 13:23:30

标签: swiftui

我希望SwiftUI DragGesture仅在手势沿特定方向(水平/垂直)启动时才开始。有可能吗?

3 个答案:

答案 0 :(得分:1)

相当老的问题,但在别处找不到答案。

您可以轻松检查是向左滑动还是向右滑动,因为手势会返回其结束状态,其中包含起始位置和最终位置。

Text("Hello").gesture(DragGesture(minimumDistance: 100).onEnded { endedGesture in
                if (endedGesture.location.x - endedGesture.startLocation.x) > 0 {
                    print("Left")
                } else {
                    print("Right")
                }
}

答案 1 :(得分:0)

是的,是通过将手势转换的两个组件(水平或垂直)之一应用于视图偏移。

这里的行为实现为ViewModifier

struct DraggableModifier : ViewModifier {

    enum Direction {
        case vertical
        case horizontal
    }

    let direction: Direction

    @State private var draggedOffset: CGSize = .zero

    func body(content: Content) -> some View {
        content
        .offset(
            CGSize(width: direction == .vertical ? 0 : draggedOffset.width,
                   height: direction == .horizontal ? 0 : draggedOffset.height)
        )
        .gesture(
            DragGesture()
            .onChanged { value in
                self.draggedOffset = value.translation
            }
            .onEnded { value in
                self.draggedOffset = .zero
            }
        )
    }

}

演示:

struct ContentView: View {

    var body: some View {
        VStack {
            Spacer(minLength: 100)
            HStack {
                Rectangle()
                    .foregroundColor(.green)
                    .frame(width: 100, height: 100)
                    .modifier(DraggableModifier(direction: .vertical))
                Text("Vertical")
            }
            Spacer(minLength: 100)
            Rectangle()
                .foregroundColor(.red)
                .frame(width: 100, height: 100)
                .modifier(DraggableModifier(direction: .horizontal))
            Text(verbatim: "Horizontal")
            Spacer(minLength: 100)
        }
    }
}

结果

enter image description here

答案 2 :(得分:0)

这只会在手势水平移动而不是垂直移动时移动视图。 isDragging 布尔值确保在满足第一个条件后,视图也会垂直移动。这不是必需的,但它有助于更​​顺畅地拖动。

@State var dragOffset: CGSize = .zero
@State var isDragging = false

.offset(x: offset.width, y: offset.height)
        .gesture(DragGesture()
                    .onChanged { if abs($0.translation.width) > abs($0.translation.height) || isDragging {
                        self.offset = $0.translation
                        self.isDragging = true
                        
                    }
                    }
                    .onEnded {
                        isDragging = false
                        
                    })