반반 나눠서 실선 및 점선 애니메이션 효과로 그리기

 

⎯⎯⎯⎯⎯⎯∙∙∙∙∙∙∙∙∙∙

 

참고사이트 : https://stackoverflow.com/questions/47730808/dash-the-stroke-of-uibezierpath-without-using-the-cashapelayer-and-animate-this/47736224#47736224

struct Stroke {
    let start: CGPoint
    let end: CGPoint
    let lineDashPattern: [NSNumber]?

    var length: CGFloat {
        return hypot(start.x - end.x, start.y - end.y)
    }
}

class CustomView: UIView {

    private var strokes: [Stroke]?
    private var strokeIndex = 0
    private let strokeSpeed = 200.0

    func startAnimation() {
        strokes = [
            Stroke(start: CGPoint(x: bounds.minX, y: bounds.midY),
                   end: CGPoint(x: bounds.midX, y: bounds.midY),
                   lineDashPattern: nil),
            Stroke(start: CGPoint(x: bounds.midX, y: bounds.midY),
                   end: CGPoint(x: bounds.maxX, y: bounds.midY),
                   lineDashPattern: [0, 16])
        ]
        strokeIndex = 0

        animateStroke()
    }

    private func animateStroke() {
        guard let strokes = strokes, strokeIndex < strokes.count else { return }

        let stroke = strokes[strokeIndex]

        let shapeLayer = CAShapeLayer()
        shapeLayer.lineCap = kCALineCapRound
        shapeLayer.lineDashPattern = strokes[strokeIndex].lineDashPattern
        shapeLayer.lineWidth = 8
        shapeLayer.strokeColor = UIColor.red.cgColor
        layer.addSublayer(shapeLayer)

        let path = UIBezierPath()
        path.move(to: stroke.start)
        path.addLine(to: stroke.end)

        shapeLayer.path = path.cgPath

        let animation = CABasicAnimation(keyPath: "strokeEnd")
        animation.fromValue = 0
        animation.toValue = 1
        animation.duration = Double(stroke.length) / strokeSpeed
        animation.delegate = self
        shapeLayer.add(animation, forKey: nil)
    }

}

extension CustomView: CAAnimationDelegate {
    func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        guard flag else { return }

        strokeIndex += 1
        animateStroke()
    }
}

+ Recent posts