SwiftUI如何为CGPoint数组中的每个坐标点绘制独立小圆点
问题原因及解决方案
第一个ForEach方案报错修复
报错原因是CGPoint默认未遵循Hashable协议,导致ForEach无法以\.self作为元素唯一标识。可以通过扩展CGPoint实现Hashable解决:
extension CGPoint: Hashable { public func hash(into hasher: inout Hasher) { hasher.combine(x) hasher.combine(y) } }
除此之外你原有代码里的Circle没有设置尺寸和位置,就算修复报错也无法显示在对应CGPoint的位置,完整修复代码如下:
struct FaceFigure : View { @ObservedObject var ce : CameraEngine var size: CGSize var body: some View { if !ce.allFaceArray.isEmpty{ ZStack{ ForEach(ce.allFaceArray, id: \.self) { point in Circle() .fill(Color.green) .frame(width: 4, height: 4) // 半径2对应直径4 .position(point) } } } } }
如果不想全局扩展CGPoint,也可以选择遍历数组索引:
ForEach(ce.allFaceArray.indices, id: \.self) { index in let point = ce.allFaceArray[index] Circle() .fill(Color.green) .frame(width: 4, height: 4) .position(point) }
第二个自定义Shape方案多余连线修复
出现连线是因为Path绘制多个子路径时,默认会将上一个子路径的终点和下一个子路径的起点自动连接,只需要每次绘制新圆点前调用move(to:)移动到新圆点的起始位置,断开和上一个路径的连接即可。修复后的Shape代码:
struct MakeCircle: Shape { var arrayViso: [CGPoint] func path(in rect: CGRect) -> Path { var path = Path() let radius: CGFloat = 2 for punti in arrayViso { // 移动到当前圆的右边缘起始点,断开与上一个路径的连接 path.move(to: CGPoint(x: punti.x + radius, y: punti.y)) path.addArc( center: punti, radius: radius, startAngle: Angle(degrees: 0), endAngle: Angle(degrees: 360), clockwise: true ) } return path } }
调用时如果需要同时实现填充+描边效果,需要调整修饰符顺序:
struct FaceFigure : View { @ObservedObject var ce : CameraEngine var size: CGSize var body: some View { if !ce.allFaceArray.isEmpty{ ZStack{ MakeCircle(arrayViso: ce.allFaceArray) .fill(Color.green) .stroke(lineWidth: 2.0) } } } }
内容的提问来源于stack exchange,提问作者Damiano Miazzi
相关产品推荐
相关产品推荐

