SwiftUI,为Array中的每个CGpoint创建一个圆

SwiftUI, create a circle for each CGpoint in Array

我有一个 CGPoint 数组,我试图为这个数组中的每个 CGPoint 位置画一个小圆圈(使用 SwiftUI)。

我尝试了不同的方法,但都没有成功,我正在寻求帮助。

我的阵列:CGPoint 称为“allFaceArray”

第一次尝试(不起作用)抛出错误:Generic struct 'ForEach' requires that 'CGPoint' conform to 'Hashable'

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().stroke(lineWidth: 2.0).fill(Color.green)
                }

            }
        }
    }
}

第二次尝试我做了一个自定义形状

struct MakeCircle: Shape {
    var arrayViso: [CGPoint]
    func path(in rect: CGRect) -> Path {
        var path = Path()
        for punti in arrayViso{
            
            let radius = 2
            path.addArc(
                center: punti,
                radius: CGFloat(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)
                   .stroke(lineWidth: 2.0)
                  .fill(Color.green)
            }
        }
    }
}

但是像这样每个点都用一条线相互连接我不知道为什么...

感谢帮助

当你找到 Generic struct 'ForEach' requires that 'CGPoint' conform to 'Hashable' 时,让 CGPoint 符合 Hashable 将是解决它的一种方法。

请使用此扩展程序并重试您的第一次尝试:

extension CGPoint: Hashable {
    public func hash(into hasher: inout Hasher) {
        hasher.combine(x)
        hasher.combine(y)
    }
}

可以使用第一种方法。虽然不能直接为 CGPoint 数组调用 ForEach()。相反,您可以将 ForEachRange<T> 一起使用,如下所示


struct ContentView: View {

    var allFaceArray = [
        CGPoint(x: 0, y: 0),
        CGPoint(x: 30, y: 50),
        CGPoint(x: 100, y: 100),
        CGPoint(x: 100, y: 500),
    ]
    var body: some View {
        ZStack {
            ForEach(0..<allFaceArray.count) { x in //<- Passing the count of the array as a range
                Circle().stroke(lineWidth: 2.0).fill(Color.green)
                    .position(allFaceArray[x])
            }
        }
    }
}

以上代码的输出是,

对于第二种方法,您可以为数组中的每个点创建一个单独的路径,并将它们添加到您已经定义为 var path = Path() 的路径中。这样你的第二种方法就可以正常工作

struct MakeCircle: Shape {
    var arrayViso: [CGPoint]
    func path(in rect: CGRect) -> Path {
        var path = Path()
        for punti in arrayViso{
            var circle = Path()
            let radius = 2

            circle.addArc(
                center: punti,
                radius: CGFloat(radius),
                startAngle: Angle(degrees: 0),
                endAngle: Angle(degrees: 360),
                clockwise: true)

            path.addPath(circle)
        }
        return path
    }
}