在SwiftUI中如何检测Tap手势?

huangapple go评论51阅读模式
英文:

How to detect TapGesture in SwiftUI?

问题

我正在编写一个容器,它在相应的边框上有两个按钮,应该能够在容器内添加内部线条。之前线条是一个接一个地添加的,但我希望用户能够决定在哪里生成这些线条。边框上的按钮覆盖整个边框,所以逻辑是让用户点击边框按钮,程序应该在那个位置生成线条。我使用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()
}

请注意,我只返回代码的翻译部分,不包括其他内容。

英文:

I am writing a container that has two buttons on corresponding borders which should be able to add inner lines inside the container. Previously the lines were being added one after another, but I want for the user to decide where to generate those lines. And the buttons on the borders cover the whole border so the logic is to let users tap on a border-button and the program should generate the line right at that location. I achieved it with DragGesture, but I want the users to tap the button not drag them and I am not able to figure out how can I replace the DragGesture here with TapGesture.

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)

And here are the adding functions:

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()
    }

答案1

得分: 2

以下是您要翻译的代码部分:

要获取当前的点击位置,您可以使用.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 {
    // 您需要两个CGPoint来标识用户点击的位置
    @State private var startTapLocation: CGPoint?
    @State private var endTapLocation: CGPoint?
    
    var body: some View {
        GeometryReader { geometry in
            ZStack {
                // 背景
                Color.white
                
                // 绘制线条
                if let start = startTapLocation, let end = endTapLocation {
                    Path { path in
                        path.move(to: start)
                        path.addLine(to: end)
                    }
                    .stroke(Color.black, lineWidth: 2)
                }
            }
            // 用于识别点击的onTapGestures
            .onTapGesture { location in
                if startTapLocation == nil && endTapLocation == nil {
                    print("设置 startTapLocation,endTap 为空")
                    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("设置 startTapLocation,endTap 不为空")
                } else if startTapLocation != nil && endTapLocation == nil {
                    endTapLocation = CGPoint(x: location.x, y: location.y)
                    print("设置 endTapLocation")
                } else if startTapLocation != nil && endTapLocation != nil {
                    startTapLocation = CGPoint(x: location.x, y: location.y)
                    print("再次设置 startTapLocation")
                }
                
                print("开始点击位置: \(String(describing: startTapLocation)) , 结束点击位置: \(String(describing: endTapLocation))")
            }
        }
    }
}

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

英文:

To get the current tap location you can use the .onTapGesture functionality and create yourself a CGPoint from your tap like this..

    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()
}

Edit:
Because it seemed that I was not clear enough I created a short programm with this drawing functionality.

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))")
			}
		}
	}
}

You need to add this functionality to your existing View.

huangapple
  • 本文由 发表于 2023年6月8日 20:44:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76431984.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定