Swift 3.1 CAShapeLayer

Created By: Debasis Das (23-May-2017)
In this post we will explore the CAShapeLayer and create different sample CAShapeLayer and in some case animate a few of the properties
In our ViewController class we will add a rootLayer which is a CALayer and set the rootLayer as the layer of the view.
once the rootLayer is created, we will call different function that will create different CAShapeLayer and will add to the root layer

swift 3.1 cashapelayer sample code Swift 3.1 CAShapeLayer Simple Line

swift 3.1 cashapelayer sample code – Simple line

Swift 3.1 CAShapeLayer Line Dash Pattern

swift 3.1 cashapelayer sample code – line dash pattern

Swift 3.1 CAShapeLayer Path Animation

Swift 3.1 CAShapeLayer Ant Marching Animation

Swift 3.1 CAShapeLayer from NSBezierPath

Swift 3.1 Circle CAShapeLayer CGMutablePath

Swift 3.1 CAShapeLayer Rectangle

Swift 3.1 CAShapeLayer Triangle

Swift 3.1 CAShapeLayer Star
Step 1:

let rootLayer = CALayer()    
override func viewDidLoad() {
        super.viewDidLoad()
        rootLayer.frame = self.view.frame
        rootLayer.backgroundColor = NSColor.white.cgColor
        self.view.layer = rootLayer
        self.view.wantsLayer = true
        //linesShapeLayers()
        //linesShapeLayersLineDashPattern()
        //marchingAntAnimationUsingCAShapeLayer()
        //differentLineCaps()
        //circleShapeLayerSampleOne()
        //circleShapeLayerSampleTwo()
        //rectangeCAShapeLayer()
        //triangleCAShapeLayer()
        //starCAShapeLayer()
        //animateCAShapeLayerDrawing()
    }

CAShapeLayer – Simple Line

Swift 3.1 CAShapeLayer Simple Line

    func linesShapeLayers(){
        let shapeLayer = CAShapeLayer()
        shapeLayer.strokeColor = NSColor.black.cgColor
        shapeLayer.lineWidth = 10
        let path = CGMutablePath()
        path.addLines(between: [CGPoint(x: 20, y: 50),CGPoint(x: 250, y: 50)])
        shapeLayer.path = path
        rootLayer.addSublayer(shapeLayer)
    }

CAShapeLayer – Line Dash Pattern

Swift 3.1 CAShapeLayer Line Dash Pattern

    

    func linesShapeLayersLineDashPattern(){
        let shapeLayer = CAShapeLayer()
        shapeLayer.strokeColor = NSColor.black.cgColor
        shapeLayer.lineWidth = 10
        shapeLayer.lineDashPattern = [10,5]
        let path = CGMutablePath()
        path.addLines(between: [CGPoint(x: 20, y: 50),CGPoint(x: 450, y: 50)])
        shapeLayer.path = path
        rootLayer.addSublayer(shapeLayer)
    }

CAShapeLayer – Different Line Caps

Swift 3.1 CAShapeLayer - Different Line Caps

    //Different Types of Line Caps
    func differentLineCaps(){
        let shapeLayer1 = CAShapeLayer()
        shapeLayer1.strokeColor = NSColor.black.cgColor
        shapeLayer1.lineWidth = 20
        shapeLayer1.lineCap = kCALineCapButt
        let path1 = CGMutablePath()
        path1.addLines(between: [CGPoint(x: 20, y: 50),CGPoint(x: 250, y: 50)])
        shapeLayer1.path = path1
        rootLayer.addSublayer(shapeLayer1)

        let shapeLayer2 = CAShapeLayer()
        shapeLayer2.strokeColor = NSColor.black.cgColor
        shapeLayer2.lineWidth = 20
        shapeLayer2.lineCap = kCALineCapRound
        let path2 = CGMutablePath()
        path2.addLines(between: [CGPoint(x: 20, y: 100),CGPoint(x: 250, y: 100)])
        shapeLayer2.path = path2
        rootLayer.addSublayer(shapeLayer2)

        let shapeLayer3 = CAShapeLayer()
        shapeLayer3.strokeColor = NSColor.black.cgColor
        shapeLayer3.lineWidth = 20
        shapeLayer3.lineCap = kCALineCapSquare
        let path3 = CGMutablePath()
        path3.addLines(between: [CGPoint(x: 20, y: 150),CGPoint(x: 250, y: 150)])
        shapeLayer3.path = path3
        rootLayer.addSublayer(shapeLayer3)

    }

CAShapeLayer Marching Ant Animation

Swift 3.1 CAShapeLayer Ant Marching Animation

    func marchingAntAnimationUsingCAShapeLayer(){
        let shapeLayer = CAShapeLayer()
        shapeLayer.strokeColor = NSColor.black.cgColor
        shapeLayer.lineWidth = 10
        shapeLayer.lineDashPattern = [10,5,5,5]
        let path = CGMutablePath()
        path.addLines(between: [CGPoint(x: 20, y: 50),CGPoint(x: 450, y: 50)])
        shapeLayer.path = path
        
        let lineDashAnimation = CABasicAnimation(keyPath: "lineDashPhase")
        lineDashAnimation.fromValue = 0
        lineDashAnimation.toValue = shapeLayer.lineDashPattern?.reduce(0) { $0 + $1.intValue }
        lineDashAnimation.duration = 0.5
        lineDashAnimation.repeatCount = Float.greatestFiniteMagnitude
        
        shapeLayer.add(lineDashAnimation, forKey: nil)
        rootLayer.addSublayer(shapeLayer)
    }

CAShapeLayer Circle Shape using NSBezierPath

Swift 3.1 CAShapeLayer from NSBezierPath

func circleShapeLayerSampleOne(){
        let layer = CAShapeLayer()
        let rect = NSRect(x: 10, y: 10, width: 200, height: 200)
        let bezierPath = NSBezierPath(roundedRect: rect, xRadius: 100, yRadius: 100)
        layer.path = bezierPath.cgPath //Note: There is no available methods called cgPath for a NSBezierPath and thus we are extending NSBezierPath to add the cgPath method
        layer.fillColor = NSColor.red.cgColor
        rootLayer.addSublayer(layer)
    }
extension NSBezierPath {
    
    public var cgPath: CGPath {
        let path = CGMutablePath()
        var points = [CGPoint](repeating: .zero, count: 3)
        
        for i in 0 ..< self.elementCount {
            let type = self.element(at: i, associatedPoints: &points)
            switch type {
            case .moveToBezierPathElement:
                path.move(to: points[0])
            case .lineToBezierPathElement:
                path.addLine(to: points[0])
            case .curveToBezierPathElement:
                path.addCurve(to: points[2], control1: points[0], control2: points[1])
            case .closePathBezierPathElement:
                path.closeSubpath()
            }
        }
        
        return path
    }
}

CAShapeLayer Circle Shape using CGMutablePath

Swift 3.1 Circle CAShapeLayer CGMutablePath

    func circleShapeLayerSampleTwo(){
        let layer = CAShapeLayer()
        let path = CGMutablePath()
        let centerPoint = CGPoint(x: 200, y: 200)
        path.addArc(center: centerPoint, radius: 100, startAngle: CGFloat(0.0), endAngle: CGFloat(Double.pi) * 2, clockwise: true)
        layer.path = path
        layer.strokeColor = NSColor.black.cgColor
        layer.lineWidth = 5.0
        layer.fillColor = NSColor.red.cgColor
        rootLayer.addSublayer(layer)
    }

CAShapeLayer Triangle Shape

Swift 3.1 CAShapeLayer Triangle

    func triangleCAShapeLayer(){
        let layer = CAShapeLayer()
        let path = CGMutablePath()
        path.move(to: CGPoint(x: 20.0, y: 20.0))
        path.addLine(to: CGPoint(x: 100.0, y: 120.0))
        path.addLine(to: CGPoint(x: 180.0, y: 20.0))
        path.addLine(to: CGPoint(x: 20.0, y: 20.0))
        layer.strokeColor = NSColor.black.cgColor
        layer.lineWidth = 3.0
        layer.fillColor = NSColor.red.cgColor
        layer.path = path
        rootLayer.addSublayer(layer)
        
    }

CAShapeLayer Rectangle Shape

Swift 3.1 CAShapeLayer Rectangle

func rectangeCAShapeLayer(){
        let layer = CAShapeLayer()
        let path = CGMutablePath()
        path.addRect(CGRect(x: 150, y: 150, width: 100.0, height: 100.0))
        layer.path = path
        layer.strokeColor = NSColor.black.cgColor
        layer.lineWidth = 3.0
        layer.fillColor = NSColor.red.cgColor
        rootLayer.addSublayer(layer)
        
    }

CAShapeLayer Star Shape

Swift 3.1 CAShapeLayer Star

    func starCAShapeLayer(){
        let shapeLayer = CAShapeLayer()
        let path = CGMutablePath();
        path.move(to: CGPoint(x: 42.25, y: 0))
        path.addLine(to: CGPoint(x: 61.13, y: 23))
        path.addLine(to: CGPoint(x: 88.29, y: 30.75))
        path.addLine(to: CGPoint(x: 70.95, y: 52.71))
        path.addLine(to: CGPoint(x: 71.85, y: 80.5))
        path.addLine(to: CGPoint(x: 45.25, y: 71.07))
        path.addLine(to: CGPoint(x: 18.65, y: 80.5))
        path.addLine(to: CGPoint(x: 19.55, y: 52.71))
        path.addLine(to: CGPoint(x: 2.21, y: 30.75))
        path.addLine(to: CGPoint(x: 29.37, y: 23))
        path.addLine(to: CGPoint(x: 45.25, y: 0))

        shapeLayer.path = path;
        shapeLayer.fillColor = NSColor.red.cgColor;
        shapeLayer.lineCap = kCALineCapButt;
        shapeLayer.lineDashPattern = nil;
        shapeLayer.lineDashPhase = 0.0;
        shapeLayer.lineJoin = kCALineJoinMiter;
        shapeLayer.lineWidth = 3.0;
        shapeLayer.miterLimit = 10.0;
        shapeLayer.strokeColor = NSColor.black.cgColor;
        rootLayer.addSublayer(shapeLayer)
        
    }

CAShapeLayer Path Animation

Swift 3.1 CAShapeLayer Path Animation

   func animateCAShapeLayerDrawing(){
        let layer = CAShapeLayer()
        let path = CGMutablePath()
        let centerPoint = CGPoint(x: 200, y: 200)
        path.addArc(center: centerPoint, radius: 100, startAngle: CGFloat(0.0), endAngle: CGFloat(Double.pi) * 2, clockwise: true)
        layer.path = path
        layer.strokeColor = NSColor.black.cgColor
        layer.lineWidth = 5.0
        layer.fillColor = nil
        rootLayer.addSublayer(layer)
        
        let pathAnimation = CABasicAnimation(keyPath: "strokeEnd")
        pathAnimation.duration = 5.0
        pathAnimation.fromValue = 0.0
        pathAnimation.toValue = 1.0
        pathAnimation.repeatCount = Float.greatestFiniteMagnitude
        layer.add(pathAnimation, forKey: "strokeEndAnimation")

        let indicatorLayer = CALayer()
        indicatorLayer.bounds = CGRect(x: 0, y: 0, width: 10.0, height: 10.0)
        indicatorLayer.cornerRadius = 5.0
        indicatorLayer.backgroundColor = NSColor.red.cgColor
        rootLayer.addSublayer(indicatorLayer)
        let indicatorAnimation = CAKeyframeAnimation(keyPath: "position")
        indicatorAnimation.duration = 5.0
        indicatorAnimation.path = path
        indicatorAnimation.calculationMode = kCAAnimationPaced
        indicatorAnimation.repeatCount = Float.greatestFiniteMagnitude
        indicatorLayer.add(indicatorAnimation, forKey: "position")
    }

Posted in Swift, Swift 3.1 Tagged with: , , , , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

*