You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 07:57:00