Files
GitHawk/Playgrounds/ButtonAnimation.playground/Contents.swift
2017-10-03 16:18:31 +02:00

185 lines
5.1 KiB
Swift

//: 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()