104 lines
2.9 KiB
Swift
104 lines
2.9 KiB
Swift
//
|
|
// CALayer+Animate.swift
|
|
// PlusBank
|
|
//
|
|
// Created by Valentin Titov on 04.02.2021.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
extension CALayer {
|
|
|
|
public func animate() -> CALayerAnimate {
|
|
return CALayerAnimate(layer: self)
|
|
}
|
|
}
|
|
|
|
public class CALayerAnimate {
|
|
|
|
private var animations: [String: CAAnimation]
|
|
private var duration: CFTimeInterval
|
|
let layer: CALayer
|
|
|
|
init(layer: CALayer) {
|
|
self.animations = [String: CAAnimation]()
|
|
self.duration = 0.25 // second
|
|
self.layer = layer
|
|
}
|
|
|
|
public func shadowOpacity(shadowOpacity: Float) -> CALayerAnimate {
|
|
let key = "shadowOpacity"
|
|
let animation = CABasicAnimation(keyPath: key)
|
|
animation.fromValue = layer.shadowOpacity
|
|
animation.toValue = shadowOpacity
|
|
animation.isRemovedOnCompletion = false
|
|
animation.fillMode = .forwards
|
|
animations[key] = animation
|
|
return self
|
|
}
|
|
|
|
public func shadowRadius(shadowRadius: CGFloat) -> CALayerAnimate {
|
|
let key = "shadowRadius"
|
|
let animation = CABasicAnimation(keyPath: key)
|
|
animation.fromValue = layer.shadowRadius
|
|
animation.toValue = shadowRadius
|
|
animation.isRemovedOnCompletion = false
|
|
animation.fillMode = CAMediaTimingFillMode.forwards
|
|
animations[key] = animation
|
|
return self
|
|
}
|
|
|
|
public func shadowOffsetX(shadowOffsetX: CGFloat) -> CALayerAnimate {
|
|
let key = "shadowOffset"
|
|
|
|
var toValue: CGSize
|
|
if let currentAnimation = animations[key] as? CABasicAnimation, let currentValue = currentAnimation.toValue {
|
|
toValue = (currentValue as AnyObject).cgSizeValue
|
|
} else {
|
|
toValue = .zero
|
|
}
|
|
toValue.width = shadowOffsetX
|
|
|
|
let animation = CABasicAnimation(keyPath: key)
|
|
animation.fromValue = NSValue(cgSize: layer.shadowOffset)
|
|
animation.toValue = NSValue(cgSize: toValue)
|
|
animation.isRemovedOnCompletion = false
|
|
animation.fillMode = CAMediaTimingFillMode.forwards
|
|
animations[key] = animation
|
|
return self
|
|
}
|
|
|
|
public func shadowOffsetY(shadowOffsetY: CGFloat) -> CALayerAnimate {
|
|
let key = "shadowOffset"
|
|
|
|
var toValue: CGSize
|
|
if let currentAnimation = animations[key] as? CABasicAnimation, let currentValue = currentAnimation.toValue {
|
|
toValue = (currentValue as AnyObject).cgSizeValue
|
|
} else {
|
|
toValue = .zero
|
|
}
|
|
toValue.height = shadowOffsetY
|
|
|
|
let animation = CABasicAnimation(keyPath: key)
|
|
animation.fromValue = NSValue(cgSize: layer.shadowOffset)
|
|
animation.toValue = NSValue(cgSize: toValue)
|
|
animation.isRemovedOnCompletion = false
|
|
animation.fillMode = CAMediaTimingFillMode.forwards
|
|
animations[key] = animation
|
|
return self
|
|
}
|
|
|
|
public func duration(duration: CFTimeInterval) -> CALayerAnimate {
|
|
self.duration = duration
|
|
return self
|
|
}
|
|
|
|
public func start() {
|
|
for (key, animation) in animations {
|
|
animation.duration = duration
|
|
layer.removeAnimation(forKey: key)
|
|
layer.add(animation, forKey: key)
|
|
}
|
|
}
|
|
}
|