如何在SwiftUI中检测TapGesture?

gcmastyq  于 2023-06-21  发布在  Swift
关注(0)|答案(1)|浏览(111)

我写了一个容器,有两个按钮,相应的边界,应该能够添加内部线内的容器。以前,这些线是一个接一个地添加的,但我希望用户决定在哪里生成这些线。边框上的按钮覆盖了整个边框,所以逻辑是让用户点击一个边框按钮,程序应该在那个位置生成一条线。我用DragGesture实现了它,但我希望用户点击按钮而不是拖动它们,我不知道如何用TapGesture替换DragGesture。

Button(action: {
                    addHorizontalLine()
                    self.selectedId = self.id //
                }) {
                    Rectangle()
                        .foregroundColor(.clear)
                }
                .frame(width: 4, height: rectangleSize.height)
                .background(Color.blue)
                .position(x: 4 / 2, y: rectangleSize.height / 2)
                .gesture(
                    DragGesture(minimumDistance: 0)
                    .onEnded { value in
                        tappedPointY = value.location.y / rectangleSize.height
                        addHorizontalLine()
                            }
                        )
                .zIndex(1)

                Button(action: {
                    addVerticalLine()

                    self.selectedId = self.id //
                }) {
                    Rectangle()
                        .foregroundColor(.clear)
                }
                .frame(width: rectangleSize.width, height: 4)
                .background(Color.blue)
                .position(x: rectangleSize.width / 2, y: 4 / 2)
                .gesture(
                    DragGesture(minimumDistance: 0)
                    .onEnded { value in
                        tappedPointX = value.location.x / rectangleSize.width
                        addVerticalLine()
                            }
                    )//
                .zIndex(1)

以下是添加功能:

private func addHorizontalLine() {
        let y = rectangleSize.height * tappedPointY
        horizontalLines.append(y)
        horizontalLines = horizontalLines.sorted()
    }

    private func addVerticalLine() {
        let x = rectangleSize.width * tappedPointX
        verticalLines.append(x)
        verticalLines = verticalLines.sorted()
    }
2vuwiymt

2vuwiymt1#

要获取当前的点击位置,您可以使用.onTapGesture功能,并从您的点击中创建一个CGPoint,如下所示。

var body: some View {
      VStack {
        Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Hello, world!")
        }
        .onTapGesture { location in
            let tap = CGPoint(x: location.x, y: location.y)
            print("\(tap)")
        }
        .padding()
}

编辑:因为我似乎不够清楚,我创建了一个简短的程序与此绘图功能。

struct ContentView: View {
    // you need two CGPoints to identify where the user clicked
    @State private var startTapLocation: CGPoint?
    @State private var endTapLocation: CGPoint?
    
    var body: some View {
        GeometryReader { geometry in
            ZStack {
                //Background
                Color.white
                
                // draw line
                if let start = startTapLocation, let end = endTapLocation {
                    Path { path in
                        path.move(to: start)
                        path.addLine(to: end)
                    }
                    .stroke(Color.black, lineWidth: 2)
                }
            }
            //onTapGestures to identify the taps
            .onTapGesture {
                location in
                if startTapLocation == nil && endTapLocation == nil {
                    print("set startTapLocation, endTap is empty")
                    startTapLocation = CGPoint(x: location.x, y: location.y)
                } else
                if startTapLocation == nil && endTapLocation != nil {
                    startTapLocation = CGPoint(x: location.x, y: location.y)
                    endTapLocation = CGPoint(x: 0, y: 0)
                    print("set startTapLocation, endTap is not empty")
                } else
                if (startTapLocation != nil && endTapLocation == nil) {
                    endTapLocation = CGPoint(x: location.x, y: location.y)
                    print("set endTapLocation")
                } else
                if (startTapLocation != nil && endTapLocation != nil){
                    startTapLocation = CGPoint(x: location.x, y: location.y)
                    print("set startTapLocation again")
                }
                
                print("Start tap: \(String(describing: startTapLocation)) , End Tap: \(String(describing: endTapLocation))")
            }
        }
    }
}

您需要将此功能添加到现有视图中。

相关问题