mirror of
https://github.com/zhigang1992/GitHawk.git
synced 2026-01-12 17:22:45 +08:00
playground for reaction animations
This commit is contained in:
184
Playgrounds/ButtonAnimation.playground/Contents.swift
Normal file
184
Playgrounds/ButtonAnimation.playground/Contents.swift
Normal file
@@ -0,0 +1,184 @@
|
||||
//: A UIKit based Playground for presenting user interface
|
||||
|
||||
import UIKit
|
||||
import PlaygroundSupport
|
||||
|
||||
class Button: UIView {
|
||||
let emoji = UILabel()
|
||||
let label = UILabel()
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
emoji.backgroundColor = .clear
|
||||
emoji.textAlignment = .center
|
||||
emoji.font = UIFont.systemFont(ofSize: 36)
|
||||
addSubview(emoji)
|
||||
label.backgroundColor = .clear
|
||||
label.textAlignment = .center
|
||||
label.clipsToBounds = true
|
||||
label.textColor = .black
|
||||
label.font = UIFont.systemFont(ofSize: 30)
|
||||
addSubview(label)
|
||||
}
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
let half = bounds.width/2
|
||||
emoji.frame = CGRect(x: 0, y: 0, width: half, height: bounds.height)
|
||||
label.frame = CGRect(x: half, y: 0, width: half, height: bounds.height)
|
||||
}
|
||||
}
|
||||
|
||||
class MyViewController : UIViewController {
|
||||
|
||||
var val = 0
|
||||
|
||||
let button = Button()
|
||||
let add = UIButton()
|
||||
let sub = UIButton()
|
||||
|
||||
override func loadView() {
|
||||
let view = UIView()
|
||||
view.backgroundColor = .white
|
||||
self.view = view
|
||||
button.frame = CGRect(x: 0, y: 0, width: 90, height: 30)
|
||||
view.addSubview(button)
|
||||
add.setTitle("Add", for: .normal)
|
||||
add.setTitleColor(.blue, for: .normal)
|
||||
add.sizeToFit()
|
||||
add.addTarget(self, action: #selector(MyViewController.onAdd), for: .touchUpInside)
|
||||
view.addSubview(add)
|
||||
sub.setTitle("Sub", for: .normal)
|
||||
sub.setTitleColor(.blue, for: .normal)
|
||||
sub.sizeToFit()
|
||||
sub.addTarget(self, action: #selector(MyViewController.onSub), for: .touchUpInside)
|
||||
view.addSubview(sub)
|
||||
update(.idle)
|
||||
}
|
||||
|
||||
@objc func onAdd() {
|
||||
update(.add)
|
||||
}
|
||||
|
||||
@objc func onSub() {
|
||||
update(.sub)
|
||||
}
|
||||
|
||||
enum Update {
|
||||
case add
|
||||
case sub
|
||||
case idle
|
||||
}
|
||||
|
||||
func update(_ update: Update) {
|
||||
button.emoji.text = "🤔"
|
||||
|
||||
enum Action {
|
||||
case remove
|
||||
case add
|
||||
case incr
|
||||
case decr
|
||||
case none
|
||||
}
|
||||
|
||||
let action: Action
|
||||
switch update {
|
||||
case .add:
|
||||
if val == 0 {
|
||||
action = .add
|
||||
} else if val > 0 {
|
||||
action = .incr
|
||||
} else {
|
||||
action = .none
|
||||
}
|
||||
val += 1
|
||||
case .sub:
|
||||
if val > 1 {
|
||||
action = .decr
|
||||
} else if val == 1 {
|
||||
action = .remove
|
||||
} else {
|
||||
action = .none
|
||||
}
|
||||
val -= 1
|
||||
case .idle:
|
||||
action = .none
|
||||
}
|
||||
|
||||
print(val)
|
||||
|
||||
switch action {
|
||||
case .add:
|
||||
pop()
|
||||
case .remove:
|
||||
remove()
|
||||
case .incr:
|
||||
iterate(incr: true)
|
||||
case .decr:
|
||||
iterate(incr: false)
|
||||
case .none:
|
||||
if val <= 0 {
|
||||
button.emoji.alpha = 0
|
||||
button.label.alpha = 0
|
||||
} else {
|
||||
button.emoji.alpha = 1
|
||||
button.label.alpha = 1
|
||||
}
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
func pop() {
|
||||
print("pop")
|
||||
|
||||
button.emoji.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
|
||||
button.emoji.alpha = 0
|
||||
UIView.animate(withDuration: 0.6, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.2, options: [.curveEaseInOut], animations: {
|
||||
self.button.emoji.transform = .identity
|
||||
self.button.emoji.alpha = 1
|
||||
})
|
||||
|
||||
button.label.alpha = 0
|
||||
button.label.text = "\(val)"
|
||||
UIView.animate(withDuration: 0.3, delay: 0, options: [], animations: {
|
||||
self.button.label.alpha = 1
|
||||
})
|
||||
}
|
||||
|
||||
func remove() {
|
||||
print("remove")
|
||||
|
||||
button.label.alpha = 1
|
||||
button.emoji.transform = .identity
|
||||
button.emoji.alpha = 1
|
||||
UIView.animate(withDuration: 0.2, delay: 0, options: [], animations: {
|
||||
self.button.label.alpha = 0
|
||||
self.button.emoji.transform = CGAffineTransform(scaleX: 0.3, y: 0.3)
|
||||
self.button.emoji.alpha = 0
|
||||
})
|
||||
}
|
||||
|
||||
func iterate(incr: Bool) {
|
||||
print("iterate \(incr)")
|
||||
|
||||
let animation = CATransition()
|
||||
animation.duration = 0.25
|
||||
animation.type = kCATransitionPush
|
||||
animation.subtype = incr ? kCATransitionFromTop : kCATransitionFromBottom
|
||||
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
|
||||
button.label.layer.add(animation, forKey: "text-change")
|
||||
|
||||
button.label.text = "\(val)"
|
||||
}
|
||||
|
||||
override func viewWillLayoutSubviews() {
|
||||
super.viewWillLayoutSubviews()
|
||||
button.center = view.center
|
||||
add.center = CGPoint(x: button.frame.maxX, y: button.frame.maxY + 40)
|
||||
sub.center = CGPoint(x: button.frame.minX, y: button.frame.maxY + 40)
|
||||
}
|
||||
|
||||
}
|
||||
// Present the view controller in the Live View window
|
||||
PlaygroundPage.current.liveView = MyViewController()
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='5.0' target-platform='ios'>
|
||||
<timeline fileName='timeline.xctimeline'/>
|
||||
</playground>
|
||||
Reference in New Issue
Block a user