iOS,如何连续动画一行“跑”(“行军蚂蚁”效果)?

我必须承认我不知道在iOS中如何做到这一点 –

这里有一些代码可以产生一个很好的虚线:

《iOS,如何连续动画一行“跑”(“行军蚂蚁”效果)?》

现在,我希望该行“向上”运行:

因此,每一秒它将向上移动,itemLength * 2.0.

当然,它会从上到下包裹.

所以,DottedVertical应该完全靠它自己完成.

真的,你是如何在iOS中做到这一点的?

如果解决方案是通用的并且将“滚动”任何我想要的层或绘制的东西,那将是很好的.

比如一个游戏引擎它是微不足道的,你只需动画纹理的偏移.您是否可以在iOS中抵消图层或其他内容?

什么是最好的方式?

我猜你想用GPU(图层动画吧?)来避免融化cpu.

@IBDesignable class DottedVertical: UIView {

    @IBInspectable var dotColor: UIColor = UIColor.faveColor

    override func draw(_ rect: CGRect) {

        // say you want 8 dots, with perfect fenceposting:
        let totalCount = 8 + 8 - 1
        let fullHeight = bounds.size.height
        let width = bounds.size.width
        let itemLength = fullHeight / CGFloat(totalCount)
        let beginFromTop = !lowerHalfOnly ? 0.0 : (fullHeight * 8.0 / 15.0)
        let top = CGPoint(x: width/2, y: beginFromTop)
        let bottom = CGPoint(x: width/2, y: fullHeight)

        let path = UIBezierPath()
        path.move(to: top)
        path.addLine(to: bottom)
        path.lineWidth = width
        let dashes: [CGFloat] = [itemLength, itemLength]
        path.setLineDash(dashes, count: dashes.count, phase: 0)
        dotColor.setStroke()
        path.stroke()
}

(奖金 – 如果你在屏幕上有一些这些,他们当然必须同步.需要一个“同步”调用启动正在运行的动画,所以你可以一次启动它们通知或其他消息.)

最佳答案 讨厌回答我自己的问题,这是基于男士建议的复制和粘贴解决方案!

好的!精湛的效果……

@IBDesignable class DottedVertical: UIView {

    @IBInspectable var dotColor: UIColor = sfBlack6 { didSet {setup()} }

    override func layoutSubviews() { setup() }

    var s:CAShapeLayer? = nil

    func setup() {
        // say you want 8 dots, with perfect fenceposting:
        - calculate exactly as in the example in the question above -

        // marching ants...

        if (s == nil) {
            s = CAShapeLayer()
            self.layer.addSublayer(s!)
        }

        s!.strokeColor = dotColor.cgColor
        s!.fillColor = backgroundColor?.cgColor
        s!.lineWidth = width
        let ns = NSNumber(value: Double(itemLength))
        s!.lineDashPattern = [ns, ns]

        let path = CGMutablePath()
        path.addLines(between: [top, bottom])
        s!.path = path

        let anim = CABasicAnimation(keyPath: "lineDashPhase")
        anim.fromValue = 0
        anim.toValue = ns + ns
        anim.duration = 1.75 // seconds
        anim.repeatCount = Float.greatestFiniteMagnitude

        s!.add(anim, forKey: nil)

        self.layer.addSublayer(s!)
    }
}
点赞