- 小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
最后需要完成的效果:
首先要做的就是用CAShapeLayer画一个圆。这里先创建一个路径,把圆的中心放在视图的中心,半径设为100,然后设置起始角度和结束角度,并将clockwise设为true。然后将shapeLayer的路径设为刚才创建的路径,最后将shapeLayer添加到view的layer的sublayer中。
let shapeLayer = CAShapeLayer()
let center = view.center
let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
shapeLayer.path = circularPath.cgPath
view.layer.addSublayer(shapeLayer)
复制代码
接下来在shapeLayer外面添加一圈红色的圆圈。
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = 10
复制代码
效果如下:
接下来为view添加一个点击手势,以便后面来进行外面圆圈的动画。
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
复制代码
添加响应方法
@objc func handleTap() {
}
复制代码
在添加外面圆圈的动画时候需要用到shapeLayer,所以把shapeLayer放到外面声明让VC持有。 在viewDidLoad中将shapeLayer的.strokeEnd 设为0
shapeLayer.strokeEnd = 0
复制代码
之后在handleTap中为shapeLayer添加动画。
let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
basicAnimation.toValue = 1
basicAnimation.duration = 2
shapeLayer.add(basicAnimation, forKey: "stokeAnimation")
复制代码
这样点击之后就会画一个圆圈了。
这里有个问题就是开始的位置应该是圆的上方而不是右边,这里就需要去修改circularPath的startAngle,这样就会从圆的上方开始动画了。
let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: -CGFloat.pi / 2, endAngle: CGFloat.pi * 2, clockwise: true)
复制代码
这里还有个问题就是圆圈的头是直线而不是圆形的,这里只需要改shapeLayer的lineCap就可以了。
shapeLayer.lineCap = .round
复制代码
接下来移除掉圆圈中间的黑色部分,这里修改shapeLayer的填充色为无色。
shapeLayer.fillColor = UIColor.clear.cgColor
复制代码
接下来为进度条添加一个底部轨道(track layer)。
let trackLayer = CAShapeLayer()
trackLayer.path = circularPath.cgPath
trackLayer.strokeColor = UIColor.lightGray.cgColor
trackLayer.lineWidth = 10
trackLayer.fillColor = UIColor.clear.cgColor
trackLayer.lineCap = .round
复制代码
现在的效果:
完整代码:
import UIKit
class ViewController: UIViewController {
let shapeLayer = CAShapeLayer()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let center = view.center
let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: -CGFloat.pi / 2, endAngle: CGFloat.pi * 2, clockwise: true)
let trackLayer = CAShapeLayer()
trackLayer.path = circularPath.cgPath
trackLayer.strokeColor = UIColor.lightGray.cgColor
trackLayer.lineWidth = 10
trackLayer.fillColor = UIColor.clear.cgColor
trackLayer.lineCap = .round
view.layer.addSublayer(trackLayer)
shapeLayer.path = circularPath.cgPath
shapeLayer.strokeEnd = 0
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = 10
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.lineCap = .round
view.layer.addSublayer(shapeLayer)
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
}
@objc func handleTap() {
let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
basicAnimation.toValue = 1
basicAnimation.duration = 2
basicAnimation.fillMode = .forwards
basicAnimation.isRemovedOnCompletion = false
shapeLayer.add(basicAnimation, forKey: "stokeAnimation")
}
}
复制代码