Search code examples
iossprite-kituibezierpathcashapelayerskshapenode

The effect displayed by SKShapeNode is different from that of CAShapelayer


I am going to use SKShapeNode to display a Bezier curve graph, but the displayed effect is very strange, and it is not the same as the one displayed by CAShapeLayer. I don't know what is wrong. Does anyone know the problem?

Here is a screenshot of the effect I showed in two different ways.

The effect displayed by CAShapeLayer looks normal and is as expected

the effect displayed by SKShapeNode misses some lines

here is my main code:

let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: 54.5, y: 244.5))
bezierPath.addCurve(to: CGPoint(x: 54.5, y: 164.5), controlPoint1: CGPoint(x: 53.5, y: 243.5), controlPoint2: CGPoint(x: 29.5, y: 201.5))
bezierPath.addCurve(to: CGPoint(x: 54.5, y: 70.5), controlPoint1: CGPoint(x: 79.5, y: 127.5), controlPoint2: CGPoint(x: 54.5, y: 70.5))
bezierPath.addLine(to: CGPoint(x: 227.5, y: 70.5))
bezierPath.addCurve(to: CGPoint(x: 227.5, y: 164.5), controlPoint1: CGPoint(x: 227.5, y: 70.5), controlPoint2: CGPoint(x: 254.5, y: 127.5))
bezierPath.addCurve(to: CGPoint(x: 227.5, y: 244.5), controlPoint1: CGPoint(x: 200.5, y: 201.5), controlPoint2: CGPoint(x: 227.5, y: 244.5))
bezierPath.addCurve(to: CGPoint(x: 54.5, y: 244.5), controlPoint1: CGPoint(x: 227.5, y: 244.5), controlPoint2: CGPoint(x: 55.5, y: 245.5))
bezierPath.close()


let scene = SKScene.init(size: CGSize.init(width: 300, height: 300))
scene.backgroundColor = UIColor.white
self.contentView.presentScene(scene)

let node = SKShapeNode.init()
node.path = bezierPath.cgPath
node.lineJoin = .miter
node.lineCap = .round
node.miterLimit = 10
node.strokeColor = SKColor.blue
node.fillColor = SKColor.red
node.lineWidth = 10
node.isAntialiased = true
scene.addChild(node)

Solution

  • this code should work for you -- adding the path elements in a clockwise direction

    let N:CGFloat = 300 //box size
    let C:CGFloat = 20 //control offset
    
    let bezierPath = UIBezierPath()
    bezierPath.move(to: CGPoint(x: 0, y: 0))
    bezierPath.addCurve(to: CGPoint(x:0, y:N*0.5),
                        controlPoint1: CGPoint(x:C, y:N*0.15),
                        controlPoint2: CGPoint(x:C, y:N*0.35))
    bezierPath.addCurve(to: CGPoint(x:0, y:N),
                        controlPoint1: CGPoint(x:-C, y:N*0.65),
                        controlPoint2: CGPoint(x:-C, y:N*0.85))
    bezierPath.addLine(to: CGPoint(x:N, y:N))
    bezierPath.addCurve(to: CGPoint(x:N, y:N*0.5),
                        controlPoint1: CGPoint(x:N-C, y:N*0.85),
                        controlPoint2: CGPoint(x:N-C, y:N*0.65))
    bezierPath.addCurve(to: CGPoint(x:N, y:0),
                        controlPoint1: CGPoint(x:N+C, y:N*0.35),
                        controlPoint2: CGPoint(x:N+C, y:N*0.15))
    bezierPath.close()