2016-10-22 145 views
0

我有一个UIViewviewProgress。它是图像中的白色框。我想要一个圆形的进度条,它是图像中的绿色圆圈。进度条应该保持在白框内,但正如你所看到的那样,它是离开的。CAShapeLayer的位置不正确

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

回答

3

基本上u有几个问题的功能:

  1. 的位置不正确的layer - frame应该等于parentView中的父层的边界
  2. 你的动画将只播放一次 - 如果u想使它无限添加类似animation.repeatCount = MAXFLOAT
  3. ,以确保所有大小正确的 - 在layoutSubviews重建层,以去除先前创建一个
  4. UIBezierPath(arcCenter...将从rightSide启动路径,你也可以使用更简单的变种,如UIBezierPath(ovalInRect。考虑到这一点,你还需要为M_PI_2旋转图层,如果你想在圆圈的顶部开始绘图的话
  5. 你还应该记住,在线宽为10的情况下,你的圆圈路径的一半将是由parentView的clipSubviews收集。为了防止这种情况的改性parentLayer矩形
  6. ü也可以或许要提高lineCap可视化,买将其设定为不需要动画“圆圆”的风格
  7. progressCircle.addAnimation(animation, forKey: "ani")关键,如果ü不想从动画获取完成事件 - 我你的情况我看有没有delegate并没有removeOnCompletion标志设置好的假,这样做的假设,美实际上`吨需要

保持这一切,心中的代码可以像:

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

注: 如果妳希望动画的动画层的旋转ü也应以动画组

+0

工作就像一个魅力添加额外的动画!如果我不希望结局四舍五入,我该如何改变这种情况? –

+0

刚刚移除'progressCircle.lineCap =“round”' – gbk