Last active
September 15, 2022 17:39
-
-
Save rolandleth/421dcde6757b942ac7102fea435fd3c3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import PlaygroundSupport | |
let touchAnimationDuration: TimeInterval = 0.3 | |
var shouldPulse = true | |
class Handler { | |
@objc | |
func didTouchUpInside(_ button: UIButton) { | |
shouldPulse = true | |
pulse(button) | |
} | |
@objc | |
func flashButton() { | |
flashButtonBackground() | |
} | |
@objc | |
func didTouch(_ button: UIButton) { | |
shouldPulse = false | |
button.backgroundColor = .clear | |
button.layer.borderWidth = 1 | |
let animation = CABasicAnimation(keyPath: "borderWidth") | |
animation.fromValue = 1.5 | |
animation.toValue = 1 | |
animation.duration = touchAnimationDuration | |
button.layer.add(animation, forKey: "borderWidthIncrease") | |
UIView.animate(withDuration: touchAnimationDuration) { | |
button.transform = CGAffineTransform(scaleX: 0.95, y: 0.95) | |
} | |
} | |
@objc | |
func didLift(_ button: UIButton) { | |
button.layer.borderWidth = 1.5 | |
let animation = CABasicAnimation(keyPath: "borderWidth") | |
animation.fromValue = 1 | |
animation.toValue = 1.5 | |
animation.duration = touchAnimationDuration | |
button.layer.add(animation, forKey: "borderWidthDecrease") | |
UIView.animate(withDuration: touchAnimationDuration) { | |
button.transform = .identity | |
} | |
} | |
} | |
let handler = Handler() | |
let view = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 100)) | |
view.backgroundColor = .white | |
let button = UIButton(type: .custom) | |
view.addSubview(button) | |
let tap = UITapGestureRecognizer(target: handler, action: #selector(handler.flashButton)) | |
view.addGestureRecognizer(tap) | |
button.frame = CGRect(x: 40, y: 30, width: 120, height: 40) | |
button.setTitle("Tap me", for: .normal) | |
button.setTitleColor(.blue, for: .normal) | |
button.layer.borderWidth = 1.5 | |
button.layer.borderColor = UIColor.blue.cgColor | |
button.layer.cornerRadius = 8 | |
button.addTarget(handler, action: #selector(handler.didTouch), for: .touchDown) | |
button.addTarget(handler, action: #selector(handler.didTouchUpInside), for: .touchUpInside) | |
button.addTarget(handler, action: #selector(handler.didLift), for: .touchUpInside) | |
button.addTarget(handler, action: #selector(handler.didLift), for: .touchUpOutside) | |
// pulse(button) | |
PlaygroundPage.current.liveView = view | |
PlaygroundPage.current.needsIndefiniteExecution = true | |
func pulse(_ button: UIButton) { | |
let breatheDuration: TimeInterval = 1.8 | |
let pauseDuration: TimeInterval = 1.2 | |
let increaseAnimator = UIViewPropertyAnimator(duration: breatheDuration, curve: .easeOut) { | |
button.alpha = 1 | |
button.backgroundColor = UIColor.blue.withAlphaComponent(0.07) | |
button.transform = CGAffineTransform(scaleX: 1.05, y: 1.05) | |
} | |
let decreaseAnimator = UIViewPropertyAnimator(duration: breatheDuration, curve: .easeOut) { | |
button.alpha = 0.8 | |
button.backgroundColor = .clear | |
button.transform = CGAffineTransform(scaleX: 0.95, y: 0.95) | |
} | |
increaseAnimator.addCompletion { _ in | |
DispatchQueue.main.asyncAfter(deadline: .now() + pauseDuration) { | |
decreaseAnimator.startAnimation() | |
} | |
} | |
decreaseAnimator.addCompletion { _ in | |
guard shouldPulse else { return } | |
DispatchQueue.main.asyncAfter(deadline: .now() + pauseDuration) { | |
pulse(button) | |
} | |
} | |
increaseAnimator.startAnimation() | |
} | |
func flashButtonBackground() { | |
let animationDuration: TimeInterval = 0.2 | |
let animatorIn = UIViewPropertyAnimator(duration: animationDuration, curve: .easeOut) { | |
button.backgroundColor = UIColor.black.withAlphaComponent(0.25) | |
} | |
let animatorOut = UIViewPropertyAnimator(duration: animationDuration, curve: .easeOut) { | |
button.backgroundColor = .white | |
} | |
animatorIn.addCompletion { _ in | |
animatorOut.startAnimation() | |
} | |
animatorIn.startAnimation() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment