CAShapeLayer的位置不正确

时间:2016-10-22 15:14:34

标签: ios swift position cashapelayer cabasicanimation

我有UIView名为viewProgress。它是图像中的白框。我想要一个圆形进度条,它是图像中的绿色圆圈。进度条应该保留在白框内,但正如您所看到的那样。

如何让它留在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")
    }

我只是在viewDidLoad()

中调用该函数

enter image description here

1 个答案:

答案 0 :(得分:3)

基本上你几乎没有问题:

  1. 图层位置不正确 - 框架应该等于parentView
  2. 中父图层的边界
  3. 你的动画只会播放一次 - 如果你想让它无限添加像animation.repeatCount = MAXFLOAT
  4. 这样的东西
  5. 确保所有尺寸正确 - 在layoutSubviews中重新创建图层,同时删除之前创建的图层
  6. UIBezierPath(arcCenter...将从rightSide开始路径,您也可以使用更简单的变体UIBezierPath(ovalInRect。考虑到这一点,如果你想在圆圈的顶部开始绘图,你还需要为M_PI_2旋转图层
  7. U还应该记住,对于行宽10,一半的u&r; r圈路径将被clipSubviews的parentView捕获。为了防止这种情况,使用修改后的parentLayer rect
  8. 你也可以想要改进lineCap的可视化,购买设置为" round"式
  9. 如果你不希望从动画中获得完成事件,那么
  10. progressCircle.addAnimation(animation, forKey: "ani")关键不需要动画 - 我的情况我看到没有delegate且没有removeOnCompletion标志设置为false,所以假设你真的不需要它
  11. 记住这一切的代码可以是:

    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)
    

    结果实际上就像:

    enter image description here

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