Home > Net >  Draw multiple circles in view | ForEach
Draw multiple circles in view | ForEach

Time:10-07

What I am trying to achieve

I am learning swift. I am trying to draw a line with multiple circle on it. Then I want to be able to modify the Color of a circle when the user tap the circle. And eventually do a drag and drop for moving the circle. Such as a custom bezier curve.

Currently, I am stuck on drawing multiple circle on the line.

What I trying to do :

1 - I create an array containing CGPoint

public var PointArray:[CGPoint]=[]

2 - Then doing an Identifiable struct

private struct Positions: Identifiable {
    var id: Int
    let point: CGPoint
}

3 - With CurveCustomInit, I fill the array. I got this error

No exact matches in call to instance method 'append'

I have done a lot, but I never success at using a ForEach function in one view. I am using struct shapes as I want to customise shapes and then reuse the component. And also add a gesture function to each circle.

There is the whole code :

Note that a GeometryReader is sending the size of the view

import SwiftUI

public var PointArray:[CGPoint]=[]
public var PointArrayInit:Bool = false

private struct Positions: Identifiable {
    var id: Int
    let point: CGPoint
}

struct Arc: Shape {
    var startAngle: Angle
    var endAngle: Angle
    var clockwise: Bool
    var centerCustom:CGPoint

    func path(in rect: CGRect) -> Path {
        let rotationAdjustment = Angle.degrees(90)
        let modifiedStart = startAngle - rotationAdjustment
        let modifiedEnd = endAngle - rotationAdjustment

        var path = Path()
        path.addArc(center: centerCustom, radius: 20, startAngle: modifiedStart, endAngle: modifiedEnd, clockwise: !clockwise)

        return path
    }
}

struct CurveCustomInit: Shape {
    private var Divider:Int = 10

    func path(in rect: CGRect) -> Path {
        var path = Path()
        let xStep:CGFloat = DrawingZoneWidth / CGFloat(Divider)
        let yStep:CGFloat = DrawingZoneHeight / 2
        var xStepLoopIncrement:CGFloat = 0
        path.move(to: CGPoint(x: 0, y: yStep))
        var incr = 0
        for _ in 0...Divider {
            let Point:CGPoint = CGPoint(x: xStepLoopIncrement, y: yStep)
            let value = Positions(id:incr, point:Point )
            PointArray.append(value)
            path.addLine(to: Point)
            xStepLoopIncrement  = xStep
            incr  = 1
        }
        
        PointArrayInit = true
        return (path)
    }
}

struct TouchCurveBasic: View {
    var body: some View {
        if !PointArrayInit {
            // initialisation
            CurveCustomInit()
                .stroke(Color.red, style: StrokeStyle(lineWidth: 10, lineCap: .round, lineJoin: .round))
                .frame(width: 300, height: 300)
                .overlay(Arc(startAngle: .degrees(0),endAngle: .degrees(360),clockwise:true).stroke(Color.blue, lineWidth: 10))
        } else {
            // Update point
        }
    }
}

struct TouchCurveBasic_Previews: PreviewProvider {
    static var previews: some View {
        TouchCurveBasic()
    }
}

What I am trying to achieve :

enter image description here

CodePudding user response:

Your array PointArray contains values of type CGFloat but you are trying to append a value of type Positions. That's why you're getting this error.

  • Related