我有 2 组独立的数据,一个用于绘制一条线(a Path
),另一个用于在线某处放置一个小视图(Circle)
。
你可以想象它就像一个 Slider(实际上 UX 应该是这样的)
我想在 Red Circle View 上添加一个拖动手势,以便用户可以在线条端点之间的任何位置滑动它。但是我实施或认为的方式根本不起作用或非常糟糕。
已知的数据集是:
Start
的Line
- CGPointEnd
的Line
- CGPointPosition
的Circle View
- CGPoint
为简单起见,我添加了一些简单的点,即Top
& Bottom
,但实际上,我想要实现的是,通过获取纬度/经度坐标,在地图层上建立周长,将其转换为屏幕坐标空间并为这两个点绘制一条Path
(线),然后让用户能够标记周长,并根据用户的需要自由地沿着周长线拖动它。(每行一个标签,没有并发症)。
话虽如此,Slider 不是一个选择。
示例代码:
struct TestView: View {
@State var position = CGPoint(x: 60, y: 60)
let top = CGPoint(x: 50, y: 50)
let bottom = CGPoint(x: 300, y: 300)
var body: some View {
ZStack {
Path { path in
path.move(to: self.top)
path.addLine(to: self.bottom)
}
.stroke(Color.red, lineWidth: 5)
Circle()
.foregroundColor(.red)
.frame(width: 20)
.position(self.position)
.gesture(
DragGesture(minimumDistance: 0, coordinateSpace: .global)
.onChanged { drag in
print(drag.location)
if
self.top.x <= drag.location.x,
self.bottom.x >= drag.location.x,
self.top.y <= drag.location.y,
self.bottom.y >= drag.location.y,
self.pointOnLine(point: drag.location)
{
self.position = drag.location
}
}
)
}
}
}
检查点是否在线的辅助方法:
func pointOnLine(point: CGPoint) -> Bool {
let dxc = point.x - top.x
let dyc = point.y - top.y
let dxl = bottom.x - top.x
let dyl = bottom.y - top.y
let cross = dxc * dyl - dyc * dxl
return cross == 0
}
任何帮助表示赞赏。提前致谢。