Files
2024-09-04 04:26:04 +03:00

346 lines
10 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// 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()]
}
}