Incorrect position of CAShapeLayer

浪尽此生 提交于 2019-12-04 21:04:21

Basically u have few problems:

  1. incorrect position of your layer - frame should be equal to bounds of parent layer in parentView
  2. you animation will play only once - if u want to make it infinite add something like animation.repeatCount = MAXFLOAT
  3. to make sure that all size correct - in layoutSubviews recreate layers, with removing previously created one
  4. UIBezierPath(arcCenter... will start path from rightSide, u can also use simpler variant like UIBezierPath(ovalInRect. With this in mind u also need to rotate layer for M_PI_2 if u want to make start of drawing in the very top of circle
  5. U should also take in mind that with line width 10, half of u'r circle path will be catted by clipSubviews of parentView. To prevent this use modified parentLayer rect
  6. U can also maybe want to improve visualization of lineCap, buy setting it to "round" style
  7. progressCircle.addAnimation(animation, forKey: "ani") key for anim not required if u dont want to get completion event from animation - i your case i see there is no delegate and no removeOnCompletion flag setted to false, so make assumption that u don`t actually need it

Keeping this all in mind code can be like :

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)

and result actually like:

Note: If u want to animate rotation of animated layer u should also add additional animation in to anim group

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!