CAShapeLayer 的位置不正确

D. *_*nna 0 position cabasicanimation cashapelayer ios swift

我有一个UIViewviewProgress. 它是图像中的白框。我想要一个圆形的进度条,也就是图片中的绿色圆圈。进度条应该留在白框内,但正如您所看到的那样。

我如何让它留在里面viewProgress?在这里你有我的动画功能:

func animateView() {

        let circle = viewProgress // viewProgress is a UIView

        var progressCircle = CAShapeLayer()

        let circlePath = UIBezierPath(arcCenter: circle.center, radius: circle.bounds.midX, startAngle: -CGFloat(M_PI_2), endAngle: CGFloat(3.0 * M_PI_2), clockwise: true)

        progressCircle = CAShapeLayer ()
        progressCircle.path = circlePath.CGPath
        progressCircle.strokeColor = UIColor.whiteColor().CGColor
        progressCircle.fillColor = UIColor.clearColor().CGColor
        progressCircle.lineWidth = 10.0

        circle.layer.addSublayer(progressCircle)

        let animation = CABasicAnimation(keyPath: "strokeEnd")
        animation.fromValue = 0
        animation.toValue = 0.4
        animation.duration = 1
        animation.fillMode = kCAFillModeForwards
        animation.removedOnCompletion = false

        progressCircle.addAnimation(animation, forKey: "ani")
    }
Run Code Online (Sandbox Code Playgroud)

我只是在里面调用函数 viewDidLoad()

在此处输入图片说明

gbk*_*gbk 5

基本上你有几个问题:

  1. 图层的位置不正确 - 框架应等于 parentView 中父图层的边界
  2. 你的动画只会播放一次 - 如果你想让它无限添加类似的东西 animation.repeatCount = MAXFLOAT
  3. 确保所有尺寸都正确 - 在layoutSubviews重新创建图层中,删除以前创建的图层
  4. UIBezierPath(arcCenter...将从 开始路径rightSide,您也可以使用更简单的变体,例如UIBezierPath(ovalInRect. 考虑到这一点,如果您想在圆的最顶部开始绘制,您还需要为 M_PI_2 旋转图层
  5. 你还应该记住,当线宽为 10 时,你的圆路径的一半将被 parentView 所clipSubviews覆盖。为了防止这种使用修改 parentLayer rect
  6. 你也可能想要改进 的可视化lineCap,购买将其设置为“圆形”样式
  7. progressCircle.addAnimation(animation, forKey: "ani")如果您不想从动画中获取完成事件,则不需要动画键 - 我在您的情况下看到delegate没有removeOnCompletion设置为 false 的标志,因此假设您实际上不需要它

牢记这一切,代码可以是这样的:

let circle = UIView(frame: CGRectMake(100, 100, 100, 100)) // viewProgress is a UIView
circle.backgroundColor = UIColor.greenColor()
view.addSubview(circle)

var progressCircle = CAShapeLayer()
progressCircle.frame = view.bounds

let lineWidth:CGFloat = 10
let rectFofOval = CGRectMake(lineWidth / 2, lineWidth / 2, circle.bounds.width - lineWidth, circle.bounds.height - lineWidth)

let circlePath = UIBezierPath(ovalInRect: rectFofOval)

progressCircle = CAShapeLayer ()
progressCircle.path = circlePath.CGPath
progressCircle.strokeColor = UIColor.whiteColor().CGColor
progressCircle.fillColor = UIColor.clearColor().CGColor
progressCircle.lineWidth = 10.0
progressCircle.frame = view.bounds
progressCircle.lineCap = "round"

circle.layer.addSublayer(progressCircle)
circle.transform = CGAffineTransformRotate(circle.transform, CGFloat(-M_PI_2))

let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0
animation.toValue = 1.1
animation.duration = 1
animation.repeatCount = MAXFLOAT
animation.fillMode = kCAFillModeForwards
animation.removedOnCompletion = false
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)

progressCircle.addAnimation(animation, forKey: nil)
Run Code Online (Sandbox Code Playgroud)

结果实际上像:

在此处输入图片说明

注意: 如果你想为动画层的旋转设置动画,你还应该在动画组中添加额外的动画