Mar*_* Dm 4 cabasicanimation cashapelayer ios uibezierpath swift
我想在15秒内将角度从0度设置为360度.
动画很怪异.我知道这可能是一个开始/结束角度问题,我已经遇到了圆形动画的那种问题,但我不知道如何解决这个问题.
var circle_layer=CAShapeLayer()
var circle_anim=CABasicAnimation(keyPath: "path")
func init_circle_layer(){
let w=circle_view.bounds.width
let center=CGPoint(x: w/2, y: w/2)
//initial path
let start_angle:CGFloat = -0.25*360*CGFloat.pi/180
let initial_path=UIBezierPath(arcCenter: center, radius: w/2, startAngle: start_angle, endAngle: start_angle, clockwise: true)
initial_path.addLine(to: center)
//final path
let end_angle:CGFloat=start_angle+360*CGFloat(CGFloat.pi/180)
let final_path=UIBezierPath(arcCenter: center, radius: w/2, startAngle: start_angle, endAngle: end_angle, clockwise: true)
final_path.addLine(to: center)
//init layer
circle_layer.path=initial_path.cgPath
circle_layer.fillColor=UIColor(hex_code: "EA535D").cgColor
circle_view.layer.addSublayer(circle_layer)
//init anim
circle_anim.duration=15
circle_anim.fromValue=initial_path.cgPath
circle_anim.toValue=final_path.cgPath
circle_anim.isRemovedOnCompletion=false
circle_anim.fillMode=kCAFillModeForwards
circle_anim.delegate=self
}
func start_circle_animation(){
circle_layer.add(circle_anim, forKey: "circle_anim")
}
Run Code Online (Sandbox Code Playgroud)
Rob*_*Rob 10
您不能轻易地为a的填充设置动画UIBezierPath(或者至少在没有引入奇怪的工件的情况下,除非在良好控制的情况下).但是你可以动画strokeEnd的path的CAShapeLayer.如果你使描边路径的线宽非常宽(即最后一个圆的半径),并将路径的半径设置为圆的半径,那么你会得到类似于你正在寻找的东西.
private var circleLayer = CAShapeLayer()
private func configureCircleLayer() {
let radius = min(circleView.bounds.width, circleView.bounds.height) / 2
circleLayer.strokeColor = UIColor(hexCode: "EA535D").cgColor
circleLayer.fillColor = UIColor.clear.cgColor
circleLayer.lineWidth = radius
circleView.layer.addSublayer(circleLayer)
let center = CGPoint(x: circleView.bounds.width/2, y: circleView.bounds.height/2)
let startAngle: CGFloat = -0.25 * 2 * .pi
let endAngle: CGFloat = startAngle + 2 * .pi
circleLayer.path = UIBezierPath(arcCenter: center, radius: radius / 2, startAngle: startAngle, endAngle: endAngle, clockwise: true).cgPath
circleLayer.strokeEnd = 0
}
private func startCircleAnimation() {
circleLayer.strokeEnd = 1
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0
animation.toValue = 1
animation.duration = 15
circleLayer.add(animation, forKey: nil)
}
Run Code Online (Sandbox Code Playgroud)
对于最终的控制权,在做复杂时UIBezierPath的动画,你可以使用CADisplayLink,避免伪使用时有时会导致CABasicAnimation的path:
private var circleLayer = CAShapeLayer()
private weak var displayLink: CADisplayLink?
private var startTime: CFTimeInterval!
private func configureCircleLayer() {
circleLayer.fillColor = UIColor(hexCode: "EA535D").cgColor
circleView.layer.addSublayer(circleLayer)
updatePath(percent: 0)
}
private func startCircleAnimation() {
startTime = CACurrentMediaTime()
displayLink = {
let _displayLink = CADisplayLink(target: self, selector: #selector(handleDisplayLink(_:)))
_displayLink.add(to: .current, forMode: .commonModes)
return _displayLink
}()
}
@objc func handleDisplayLink(_ displayLink: CADisplayLink) { // the @objc qualifier needed for Swift 4 @objc inference
let percent = CGFloat(CACurrentMediaTime() - startTime) / 15.0
updatePath(percent: min(percent, 1.0))
if percent > 1.0 {
displayLink.invalidate()
}
}
private func updatePath(percent: CGFloat) {
let w = circleView.bounds.width
let center = CGPoint(x: w/2, y: w/2)
let startAngle: CGFloat = -0.25 * 2 * .pi
let endAngle: CGFloat = startAngle + percent * 2 * .pi
let path = UIBezierPath()
path.move(to: center)
path.addArc(withCenter: center, radius: w/2, startAngle: startAngle, endAngle: endAngle, clockwise: true)
path.close()
circleLayer.path = path.cgPath
}
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
configureCircleLayer()
startCircleAnimation()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
displayLink?.invalidate() // to avoid displaylink keeping a reference to dismissed view during animation
}
Run Code Online (Sandbox Code Playgroud)
产量:
| 归档时间: |
|
| 查看次数: |
3522 次 |
| 最近记录: |