Files
ContainerController/Example/ContainerControllerSwift/Framework/ButtonTapAnimations/UIButton+AllAnimations.swift
T
2024-09-04 04:26:04 +03:00

346 lines
10 KiB
Swift

//
// UIButton+AllAnimations.swift
// PlusBank
//
// Created by Рустам Мотыгуллин on 20.08.2021.
//
import UIKit
import AVFoundation
// MARK: Animations
extension UIButton {
// MARK: - Alpha
func updateChangeAlpha(with views: [UIView], visible: Alpha, value: CGFloat, duration: Speed?) {
var alpha: CGFloat = 1.0
if visible != .visible {
alpha = value
}
if let duration = duration {
UIView.animate(with: duration) {
for view in views {
view.alpha = alpha
}
}
} else {
for view in views {
view.alpha = alpha
}
}
}
// MARK: - Layer Gray
func updateLayerGray(with views: [UIView], visible: Alpha, value: CGFloat, duration: Speed?) {
guard let mainView = views.last else { return }
let shTag = 31
let spechialColor = UIColor(red: 10.0 / 255.0, green: 13.0 / 255.0, blue: 38.0 / 255.0, alpha: value)
if visible == .visible {
if let view = mainView.viewWithTag(shTag) {
view.alpha = 1
if let duration = duration {
UIView.animate(
with: duration,
animations: {
view.alpha = 0
},
completion: { fin in
view.removeFromSuperview()
}
)
} else {
view.alpha = 0
view.removeFromSuperview()
}
}
} else {
if mainView.viewWithTag(shTag) == nil {
var radius = mainView.layer.cornerRadius
if radius == 0 {
for sv in mainView.subviews {
if sv.layer.cornerRadius != 0 {
radius = mainView.layer.cornerRadius
}
if let desFig = mainView as? DesignFigure {
radius = desFig.cornerRadius
if radius == -1 {
let minSize = min(mainView.frame.width, mainView.bounds.height)
radius = minSize / 2
}
}
}
}
let shadowView = UIView(frame: mainView.bounds)
shadowView.tag = shTag
shadowView.backgroundColor = spechialColor
shadowView.layer.cornerRadius = radius
mainView.addSubview(shadowView)
shadowView.alpha = ((duration == nil) ? 1 : 0)
if let duration = duration {
if duration == .zero {
shadowView.alpha = 1
} else {
UIView.animate(with: duration) {
shadowView.alpha = 1
}
}
}
}
}
}
}
extension UIView {
// MARK: - Flash
func flash(duration: Speed = .ms200) {
let flash = CABasicAnimation(keyPath: "opacity")
flash.duration = duration.rawValue
flash.fromValue = 1
flash.toValue = 0.1
flash.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
flash.autoreverses = true
flash.repeatCount = 3
layer.add(flash, forKey: nil)
}
// MARK: - Change Color
func animationOpacity(duration: CGFloat, value: CGFloat, beginTime: CGFloat = 0.0) {
//
let pulseAnimation = CABasicAnimation(keyPath: #keyPath(CALayer.opacity))// "opacity")
pulseAnimation.fromValue = 0
pulseAnimation.toValue = 1 // 0.1
pulseAnimation.duration = 100
pulseAnimation.isRemovedOnCompletion = false
pulseAnimation.beginTime = CACurrentMediaTime() + beginTime //CACurrentMediaTime() + AVCoreAnimationBeginTimeAtZero + 1.0
pulseAnimation.fillMode = .both
pulseAnimation.isAdditive = false
// pulseAnimation.repeatCount = .infinit
layer.add(pulseAnimation, forKey: "opacityIn")
let animtingLayer: CALayer = CALayer(layer: layer)
let pulseAnimation2 = CABasicAnimation(keyPath: #keyPath(CALayer.opacity))// "opacity")
pulseAnimation2.fromValue = 1
pulseAnimation2.toValue = beginTime // 0.1
pulseAnimation2.duration = 100
pulseAnimation2.isRemovedOnCompletion = false
pulseAnimation2.beginTime = 1.0// AVCoreAnimationBeginTimeAtZero + 0.0
pulseAnimation2.fillMode = .both
pulseAnimation2.isAdditive = false
// pulseAnimation2.repeatCount = .infinit
animtingLayer.add(pulseAnimation2, forKey: "opacityOut")
layer.addSublayer(animtingLayer)
layer.opacity = 0.0
}
func animationColor(duration: Speed = .s1, colors: [UIColor]) {
// layer.removeAnimation(forKey: "backgroundColor")
// layer.sublayers?.forEach {
// $0.mask?.removeAnimation(forKey: "backgroundColor")
// }
// layer.removeAllAnimations()
// layer.removeFromSuperlayer()
let darkerColor = colors[0]
let lighterColor = colors[1]
let pulseAnimation = CABasicAnimation(keyPath: #keyPath(CALayer.backgroundColor))
pulseAnimation.fromValue = darkerColor
pulseAnimation.toValue = lighterColor
pulseAnimation.duration = 1
pulseAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
pulseAnimation.autoreverses = true
pulseAnimation.repeatCount = .infinity
pulseAnimation.isRemovedOnCompletion = false
// let color = CABasicAnimation(keyPath: "backgroundColor")
// color.fromValue = colors[0]// UIColor.green.cgColor
// color.toValue = colors[1] // UIColor.red.cgColor
// color.duration = duration.rawValue
// color.beginTime = CACurrentMediaTime() + 0.3
//// color.autoreverses = true
//// color.repeatDuration = 1
// color.autoreverses = true
// color.repeatCount = 500
// layer.cornerRadius = self.layer.cornerRadius
//// layer.add(color, forKey: "animationColor")
layer.removeAnimation(forKey: "animationColor")
layer.add(pulseAnimation, forKey: "animationColor")
backgroundColor = .clear
}
// MARK: - Pulsate
func pulsate(duration: Speed = .ms200, value: CGFloat = 0.9) {
let pulse = CASpringAnimation(keyPath: "transform.scale")
pulse.duration = duration.rawValue
pulse.fromValue = value
pulse.toValue = 1.0
pulse.autoreverses = true
pulse.repeatCount = 2
pulse.initialVelocity = 0.5
pulse.damping = 1.0
layer.add(pulse, forKey: "pulse")
}
// MARK: - Pulsate 2
func pulsateNew(visible: Alpha, value: CGFloat = 0.9) {
if visible == .visible {
animate(self, transform: .identity)
} else {
animate(self, transform: CGAffineTransform.identity.scaledBy(x: value, y: value))
}
}
private func animate(_ view: UIView, transform: CGAffineTransform) {
UIView.animate(withDuration: 0.4,
delay: 0,
usingSpringWithDamping: 0.5,
initialSpringVelocity: 3,
options: [.curveEaseInOut],
animations: {
view.transform = transform
}, completion: nil)
}
// MARK: - Shake
func shake() {
let animation = CAKeyframeAnimation(keyPath: "transform.translation.x")
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
animation.duration = 0.6
animation.values = [-20.0, 20.0, -20.0, 20.0, -10.0, 10.0, -5.0, 5.0, 0.0 ]
layer.add(animation, forKey: "shake")
}
// MARK: - Shake 2
func shakeNew(duration: Speed = .ms50) {
let shake = CABasicAnimation(keyPath: "position")
shake.duration = duration.rawValue
shake.repeatCount = 2
shake.autoreverses = true
let fromPoint = CGPoint(x: center.x - 5, y: center.y)
let fromValue = NSValue(cgPoint: fromPoint)
let toPoint = CGPoint(x: center.x + 5, y: center.y)
let toValue = NSValue(cgPoint: toPoint)
shake.fromValue = fromValue
shake.toValue = toValue
layer.add(shake, forKey: "position")
}
// MARK: - Android Pulse
func androidPulseAnimation( duration: Speed = .ms1, color: UIColor, position: CGPoint) {
let pulse = PulseAnimation(numberOfPulse: 1, radius: 200, postion: position)
pulse.animationDuration = duration.rawValue
pulse.backgroundColor = color.cgColor // #colorLiteral(red: 0.05282949957, green: 0.5737867104, blue: 1, alpha: 1)
layer.insertSublayer(pulse, below: layer)
}
}
class PulseAnimation: CALayer {
var animationGroup = CAAnimationGroup()
var animationDuration: TimeInterval = 1.5
var radius: CGFloat = 200
var numebrOfPulse: Float = Float.infinity
override init(layer: Any) {
super.init(layer: layer)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
init(numberOfPulse: Float = Float.infinity, radius: CGFloat, postion: CGPoint){
super.init()
self.backgroundColor = UIColor.black.cgColor
self.contentsScale = UIScreen.main.scale
self.opacity = 0
self.radius = radius
self.numebrOfPulse = numberOfPulse
self.position = postion
self.bounds = CGRect(x: 0, y: 0, width: radius*2, height: radius*2)
self.cornerRadius = radius
DispatchQueue.global(qos: .default).async {
self.setupAnimationGroup()
DispatchQueue.main.async {
self.add(self.animationGroup, forKey: "pulse")
}
}
}
func scaleAnimation() -> CABasicAnimation {
let scaleAnimaton = CABasicAnimation(keyPath: "transform.scale.xy")
scaleAnimaton.fromValue = NSNumber(value: 0)
scaleAnimaton.toValue = NSNumber(value: 1)
scaleAnimaton.duration = animationDuration
return scaleAnimaton
}
func createOpacityAnimation() -> CAKeyframeAnimation {
let opacityAnimiation = CAKeyframeAnimation(keyPath: "opacity")
opacityAnimiation.duration = animationDuration
opacityAnimiation.values = [0.4,0.8,0]
opacityAnimiation.keyTimes = [0,0.3,1]
return opacityAnimiation
}
func setupAnimationGroup() {
self.animationGroup.duration = animationDuration
self.animationGroup.repeatCount = numebrOfPulse
let defaultCurve = CAMediaTimingFunction(name: CAMediaTimingFunctionName.default)
self.animationGroup.timingFunction = defaultCurve
self.animationGroup.animations = [scaleAnimation(),createOpacityAnimation()]
}
}