CAKeyframeAnimation
1.透明度动画
var loginButton:UIButton?
override func viewDidLoad() {
super.viewDidLoad()
let view:UIView = UIView()
view.backgroundColor = UIColor.red
view.frame = CGRect(x: 100, y: 100, width: 200, height: 200)
self.view.addSubview(view)
let animation:CAKeyframeAnimation = CAKeyframeAnimation()
animation.duration = 10.0
animation.keyPath = "opacity"
let valuesArray:[NSNumber] = [NSNumber(value: 0.95 as Float),
NSNumber(value: 0.90 as Float),
NSNumber(value: 0.88 as Float),
NSNumber(value: 0.85 as Float),
NSNumber(value: 0.35 as Float),
NSNumber(value: 0.05 as Float),
NSNumber(value: 0.0 as Float)]
animation.values = valuesArray
animation.fillMode = kCAFillModeForwards
animation.isRemovedOnCompletion = false
view.layer.add(animation, forKey: nil)
}
2.路径动画
//创建一个可变路径
let circleKeyframePath = CGMutablePath()
//创建用于转移坐标的Transform,这样我们不用按照实际显示做坐标计算,以这个坐标做基准点。坐标为下半个弧的中心点
let circleKeyframeTransform:CGAffineTransform = CGAffineTransform(translationX: self.view.frame.size.width / 2, y: 260)
// 顺时针为false
circleKeyframePath.addArc(center: CGPoint(x: 0, y: 0), radius: 100, startAngle: CGFloat.pi , endAngle: 0, clockwise: true, transform: circleKeyframeTransform)
// circleKeyframePath.move(to: CGPoint(x: 100, y: 0), transform: circleKeyframeTransform)
circleKeyframePath.addLine(to: CGPoint(x: 100, y: -100), transform: circleKeyframeTransform)
circleKeyframePath.addLine(to: CGPoint(x: 50, y: -100), transform: circleKeyframeTransform)
circleKeyframePath.addArc(center: CGPoint(x: 0, y: -100), radius: 50, startAngle: 0 , endAngle: CGFloat.pi, clockwise: true, transform: circleKeyframeTransform)
circleKeyframePath.addLine(to: CGPoint(x: -100, y: -100), transform: circleKeyframeTransform)
circleKeyframePath.addLine(to: CGPoint(x: -100, y: 0), transform: circleKeyframeTransform)
let backgroundLayer:CAShapeLayer = CAShapeLayer()
backgroundLayer.path = circleKeyframePath
backgroundLayer.strokeColor = UIColor.blue.cgColor
backgroundLayer.lineWidth = 3
backgroundLayer.fillColor = UIColor.clear.cgColor
// backgroundLayer.backgroundColor = UIColor.red.cgColor
self.view.layer.addSublayer(backgroundLayer)
let circleView = UIView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
let redCircleLayer:CAShapeLayer = CAShapeLayer()
let redCirclePath:UIBezierPath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 20, height: 20))
redCircleLayer.path = redCirclePath.cgPath
redCircleLayer.fillColor = UIColor.red.cgColor
circleView.layer.addSublayer(redCircleLayer)
self.view.addSubview(circleView)
//创建关键帧动画对象
let circleKeyframeAnimation:CAKeyframeAnimation = CAKeyframeAnimation(keyPath: "position")
circleKeyframeAnimation.path = circleKeyframePath
circleKeyframeAnimation.duration = 5
//让 Core Animation 向被驱动的对象施加一个恒定速度,不管路径的各个线段有多长。
circleKeyframeAnimation.calculationMode = kCAAnimationPaced
circleKeyframeAnimation.repeatCount = HUGE
//让它自身也做旋转,不过是圆的看不出效果
circleKeyframeAnimation.rotationMode = kCAAnimationRotateAutoReverse
//print(circleView.layer.anchorPoint)
circleView.layer.add(circleKeyframeAnimation, forKey: nil)
动画组
1.旋转缩小平移
self.view.addSubview(loginButton!)
let rotate:CABasicAnimation = CABasicAnimation()
rotate.keyPath = "transform.rotation"
rotate.toValue = Float.pi
let scale:CABasicAnimation = CABasicAnimation()
scale.keyPath = "transform.scale"
scale.toValue = 0.0
let move:CABasicAnimation = CABasicAnimation()
move.keyPath = "transform.translation"
move.toValue = NSValue(cgPoint:CGPoint(x:217,y:-230))
let animationGroup:CAAnimationGroup = CAAnimationGroup()
animationGroup.animations = [rotate,scale,move];
animationGroup.duration = 2.0;
animationGroup.fillMode = kCAFillModeForwards;
animationGroup.isRemovedOnCompletion = false
loginButton?.layer.add(animationGroup, forKey:nil)
2.按钮点击
override func viewDidLoad() {
super.viewDidLoad()
let loginButton: CustomButton = CustomButton(frame: CGRect(x: 20, y: 230, width: self.view.frame.width-20*2,height: 50))
loginButton.setTitle("登陆", for: UIControlState())
loginButton.addTarget(self, action: #selector(ViewController.loginAction(_:event:)), for: UIControlEvents.touchUpInside)
self.view.addSubview(loginButton)
}
func loginAction(_ sender:UIButton,event:UIEvent) {
let bt:CustomButton = sender as! CustomButton
bt.startButtonAnimation(sender, event: event)
}
import UIKit
class CustomButton: UIButton {
var circleCenterX: CGFloat = 0
var circleCenterY: CGFloat = 0
var timer: Timer?
var viewRadius:CGFloat = 0
var countNum:Int = 0
var targetAnimColor: UIColor = .blue
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .red
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func startButtonAnimation(_ senderButton: UIButton, event: UIEvent) {
isUserInteractionEnabled = false
//将点击的点为中心点更改为按钮的中心值
// let touchSet = event.touches(for: senderButton)! as NSSet
// let touchArray = touchSet.allObjects
// let touch = touchArray.first as! UITouch
// let point = touch.location(in: senderButton)
// circleCenterX = point.x
// circleCenterY = point.y
circleCenterX = senderButton.frame.width / 2.0
circleCenterY = senderButton.frame.height / 2.0
timer = Timer.scheduledTimer(timeInterval: 0.02, target: self, selector: #selector(timeAction), userInfo: nil, repeats: true)
RunLoop.main.add(timer!, forMode: .commonModes)
}
func timeAction() {
countNum += 1
let dismissTime = DispatchTime.now() + Double(Int64(0 * NSEC_PER_SEC)) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: dismissTime) {
self.viewRadius += 5
self.setNeedsDisplay()
}
if(countNum>50){
countNum = 0
viewRadius = 0
timer?.invalidate()
DispatchQueue.main.asyncAfter(deadline: dismissTime, execute: {() in
self.viewRadius = 0
self.setNeedsDisplay()
})
self.isUserInteractionEnabled = true
}
}
override func draw(_ rect: CGRect) {
let ctx = UIGraphicsGetCurrentContext()!
let endangle:CGFloat = CGFloat.pi * 2
ctx.addArc(center:CGPoint(x:circleCenterX,y:circleCenterY),radius:viewRadius,startAngle:0,endAngle:endangle,clockwise:false)
let stockColor:UIColor = targetAnimColor
stockColor.setStroke()
stockColor.setFill()
ctx.fillPath()
}
}