【发布时间】:2020-06-09 08:27:24
【问题描述】:
我有一个带有图层的视图:虚线半圆、围绕半圆移动的圆以及虚线半圆上的渐变填充蒙版。我无法正确计算两个动画中的动画持续时间。目前,我的圆圈移动速度比半圆形填充中的渐变快。
这是我的代码:
class DashedCircleView: UIView {
var circleLayer = CAShapeLayer()
var circleGradientLayer = CAGradientLayer()
var movingCircleLayer = CAShapeLayer()
override init(frame: CGRect = .zero) {
super.init(frame: frame)
createDashedSemiCircle()
fillDashedSemiCircleWithGradient()
createMovingCircle()
animateGradient()
rotateMovingCircle()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
createDashedSemiCircle()
fillDashedSemiCircleWithGradient()
createMovingCircle()
animateGradient()
rotateMovingCircle()
}
private extension DashedCircleView {
func createDashedSemiCircle() {
backgroundColor = .clear
circleLayer.path = UIBezierPath(ovalIn: bounds).cgPath
circleLayer.lineWidth = 2.0
circleLayer.masksToBounds = false
circleLayer.strokeColor = UIColor.darkGray.cgColor //border of circle
circleLayer.fillColor = UIColor.clear.cgColor //inside the circle
circleLayer.lineJoin = kCALineJoinRound
circleLayer.lineDashPattern = [10, 10]
layer.addSublayer(circleLayer)
circleLayer.path = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2, y: frame.size.height / 2),
radius: min(frame.size.height, frame.size.width) / 2,
startAngle: 0,
endAngle: .pi,
clockwise: false).cgPath
}
func createMovingCircle() {
let rect = CGRect(x: 0,
y: 0,
width: 20,
height: 20)
let path = UIBezierPath(ovalIn: rect)
movingCircleLayer.fillColor = UIColor.blue.cgColor
movingCircleLayer.path = path.cgPath
movingCircleLayer.bounds = rect
layer.addSublayer(movingCircleLayer)
}
func rotateMovingCircle() {
var affineTransform = CGAffineTransform(rotationAngle: 0.0)
affineTransform = affineTransform.rotated(by: CGFloat(Double.pi))
let circlePath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2, y: frame.size.height / 2),
radius: min(frame.size.height, frame.size.width) / 2,
startAngle: .pi,
endAngle: 3 * .pi / 2,
clockwise: true).cgPath
let orbitRotateAnimation = CAKeyframeAnimation(keyPath: "position")
orbitRotateAnimation.path = circlePath
orbitRotateAnimation.duration = 4
orbitRotateAnimation.isAdditive = true
orbitRotateAnimation.repeatCount = 0
orbitRotateAnimation.calculationMode = kCAAnimationLinear
orbitRotateAnimation.rotationMode = kCAAnimationRotateAuto
orbitRotateAnimation.fillMode = kCAFillModeForwards
orbitRotateAnimation.isRemovedOnCompletion = false
movingCircleLayer.add(orbitRotateAnimation, forKey: nil)
}
func fillDashedSemiCircleWithGradient() {
layer.addSublayer(circleGradientLayer)
circleGradientLayer.mask = circleLayer
circleGradientLayer.frame = CGRect.init(origin: self.bounds.origin, size: self.frame.size)
circleGradientLayer.borderColor = UIColor.clear.cgColor
circleGradientLayer.borderWidth = 1
circleGradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
circleGradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5) // horizontal gradient
circleGradientLayer.locations = [0.0, 0.0] //max 0.88
circleGradientLayer.bounds = bounds
circleGradientLayer.colors = [
#colorLiteral(red: 0.9372549057, green: 0.3490196168, blue: 0.1921568662, alpha: 1).cgColor,
UIColor.init(red: 211/255, green: 211/255, blue: 211/255, alpha: 1.0).cgColor
]
}
func animateGradient() {
_ = 7
let endValue: Double = 23
let curValue: Double = 12
let toValue = (curValue * 0.88) / endValue
let colorsAnimation = CABasicAnimation(keyPath: #keyPath(CAGradientLayer.locations))
colorsAnimation.fillMode = kCAFillModeForwards
colorsAnimation.fromValue = [0.0, 0.0]
colorsAnimation.toValue = [toValue, toValue]
colorsAnimation.duration = 4.2
colorsAnimation.repeatCount = 0
colorsAnimation.autoreverses = false
colorsAnimation.isRemovedOnCompletion = false
circleGradientLayer.add(colorsAnimation, forKey: nil)
}
}
extension Double {
func rounded(toPlaces places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
一开始梯度不动,然后急剧加速,中途减速。
【问题讨论】:
-
不是渐变“加速和减速” ...问题是第一个“10-pt dash”几乎是垂直的,最后一个“10- pt dash”几乎是水平的。如果您注释掉这一行:
//circleGradientLayer.mask = circleLayer,您会清楚地看到它。我认为,要获得您想要的效果,您需要以与蓝色圆圈相同的速度旋转渐变层。在旋转下面的渐变层时让蒙版“保持不动”有点棘手......您可能需要使用几个相互叠加的视图。 -
您还在寻找解决方案吗?
-
@DonMag no,如何关闭话题?
-
作为一般规则...如果您已经解决了您的问题,其他用户可以将您的解决方案发布为您自己问题的答案。如果您意识到这是由于错误,请继续删除它。如果您“放弃并继续前进”,则可以保持不变……将来有人可能会遇到它并有解决方案(这将使其他用户受益)。
标签: ios swift core-graphics cashapelayer cabasicanimation