CharlieWhite
CharlieWhite

Reputation: 143

Draw Shape over another Shape

Problem :

I cannot draw a shape on another shape.

What I am trying to achieve :

Draw circles on the line.

Anyway, the circle is shifting the line. I didn't find a way to make it as swift UI seems relatively new. I am currently learning swift and I prefer swift UI rater than storyboard.

If circle and line are different struct, this is because I want to reuse the shape later on.

There is the code :

import SwiftUI

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

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: CGPoint(x: rect.midX, y: rect.midY), 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))

        for _ in 0...Divider {
            let Point:CGPoint = CGPoint(x: xStepLoopIncrement, y: yStep)
            PointArray.append(Point)
            path.addLine(to: Point)
            xStepLoopIncrement += xStep
        }

        PointArrayInit = true
        return (path)
    }
}

struct TouchCurveBasic: View {

    var body: some View {
        if !PointArrayInit {
            
            Arc(startAngle: .degrees(0), endAngle: .degrees(360), clockwise: true, centerCustom: CGPoint(x: 50, y: 400))
                .stroke(Color.blue, lineWidth: 4)

            CurveCustomInit()
                .stroke(Color.red, style: StrokeStyle(lineWidth: 10, lineCap: .round, lineJoin: .round))
                .frame(width: 300, height: 300)
        } else {
            
        }
    }
}

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

There is what I get : enter image description here

Upvotes: 0

Views: 512

Answers (1)

swiftPunk
swiftPunk

Reputation: 1

Here is an other way for you, you can limit the size of drawing with giving a frame or you can use the available size of view without limiting it or even you can use the current limit coming from parent and updated it, like i did on drawing the Line. The method that I used was overlay modifier.

struct ContentView: View {
    
    var body: some View {
        
        ArcView(radius: 30.0)
            .stroke(lineWidth: 10)
            .foregroundColor(.blue)
            .frame(width: 60, height: 60)
            .overlay(LineView().stroke(lineWidth: 10).foregroundColor(.red).frame(width: 400))

    }
    
}

struct ArcView: Shape {
    
    let radius: CGFloat

    func path(in rect: CGRect) -> Path {

        return Path { path in
            
            path.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: radius, startAngle: Angle(degrees: 0.0), endAngle: Angle(degrees: 360.0), clockwise: true)
            
        }

    }
}

struct LineView: Shape {

    func path(in rect: CGRect) -> Path {
        
        return Path { path in
            
            path.move(to: CGPoint(x: rect.minX, y: rect.midY))
            path.addLines([CGPoint(x: rect.minX, y: rect.midY), CGPoint(x: rect.maxX, y: rect.midY)])
 
        }

    }
}

result:

enter image description here

Upvotes: 1

Related Questions