这是我的代码: 导入UIKit
class circularLoaderView: UIView {
let circlePathLayer = CAShapeLayer()
let circleRadius: CGFloat = 20.0
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
configure()
}
func configure() {
circlePathLayer.frame = bounds
circlePathLayer.lineWidth = 2
circlePathLayer.fillColor = UIColor.clearColor().CGColor
circlePathLayer.strokeColor = UIColor.redColor().CGColor
layer.addSublayer(circlePathLayer)
backgroundColor = UIColor.whiteColor()
}
func circleFrame() -> CGRect {
var circleFrame = CGRect(x: 0, y: 0, width: 2*circleRadius, height: 2*circleRadius)
circleFrame.origin.x = 20
circleFrame.origin.y = 20
return circleFrame
}
func circlePath() -> UIBezierPath {
let startAngle = CGFloat(-M_PI_2)
let endAngle = startAngle + CGFloat(M_PI * 2)
return UIBezierPath(arcCenter: CGPoint(x: circleRadius, y: circleRadius), radius: circleRadius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
}
override func layoutSubviews() {
super.layoutSubviews()
circlePathLayer.frame = bounds
circlePathLayer.path = circlePath().CGPath
circlePathLayer.strokeEnd = 0.25
circlePathLayer.addAnimation(rotationAnimation, forKey: "transform.rotation")
}
let rotationAnimation: CAAnimation = {
let animation = CABasicAnimation(keyPath: "transform.rotation")
animation.fromValue = 0
animation.toValue = M_PI * 2
animation.duration = 4
animation.repeatCount = MAXFLOAT
return animation
}()
}
这是我创建CAShapeLayer的代码,它会旋转并因此加速加载器效果,但是当我添加rotationAnimation
的动画时,它会围绕中心点旋转整个CAShapeLayer,而不是CAShapeLayer本身。为什么会这样?我该如何解决?谢谢
答案 0 :(得分:0)
您应该像这样设置锚点:
layer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
答案 1 :(得分:0)
您的情况应适合大小的视图(宽度:40,高度:40)。
如果你想推广你的circularLoaderView也适用于其他尺寸,你需要
将半径指定为视图高度或宽度的一半(因为高度=宽度)。
var circleRadius: CGFloat {
return bounds.size.height/2
}
同样,您的中心也应位于视图中心
circleFrame.origin.x = bounds.size.height/2
circleFrame.origin.y = bounds.size.height/2
以下是在 Swift 3
中正常运行的修改后的代码class circularLoaderView: UIView {
let circlePathLayer = CAShapeLayer()
var circleRadius: CGFloat {
return bounds.height/2
}
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
configure()
}
func configure() {
circlePathLayer.frame = bounds
circlePathLayer.lineWidth = 2
circlePathLayer.fillColor = UIColor.clear.cgColor
circlePathLayer.strokeColor = UIColor.red.cgColor
layer.addSublayer(circlePathLayer)
backgroundColor = UIColor.white
}
//This method is not being used
/*func circleFrame() -> CGRect {
var circleFrame = CGRect(x: circleRadius , y: circleRadius, width: 2*circleRadius, height: 2*circleRadius)
circleFrame.origin.x = circleRadius
circleFrame.origin.y = circleRadius
return circleFrame
}*/
func circlePath() -> UIBezierPath {
let startAngle = CGFloat(-Double.pi/2)
let endAngle = startAngle + CGFloat(Double.pi * 2)
return UIBezierPath(arcCenter: CGPoint(x: circleRadius, y: circleRadius), radius: circleRadius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
}
override func layoutSubviews() {
super.layoutSubviews()
circlePathLayer.frame = bounds
circlePathLayer.path = circlePath().cgPath
circlePathLayer.strokeEnd = 0.25
circlePathLayer.add(rotationAnimation, forKey: "transform.rotation")
}
let rotationAnimation: CAAnimation = {
let animation = CABasicAnimation(keyPath: "transform.rotation")
animation.fromValue = 0
animation.toValue = Double.pi * 2
animation.duration = 4
animation.repeatCount = MAXFLOAT
return animation
}()
}
我知道这个问题已经发布了很长一段时间,但我希望这能解决一个正在寻找类似问题的人的问题。