Skip to content

Instantly share code, notes, and snippets.

@simme
Created February 20, 2020 10:26
Show Gist options
  • Save simme/12f241762bd37c7309e71f8632467ef5 to your computer and use it in GitHub Desktop.
Save simme/12f241762bd37c7309e71f8632467ef5 to your computer and use it in GitHub Desktop.
private final class OfferingButton: UIViewController {
@Published private var frame: CGRect = .zero
private var subscriptions: [AnyCancellable] = []
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
$frame.removeDuplicates()
.map { $0.height / 2 }
.assign(to: \.cornerRadius, on: [outlineLayer, gradientLayer])
.store(in: &subscriptions)
$frame.removeDuplicates()
.assign(to: \.frame, on: [outlineLayer, gradientLayer])
.store(in: &subscriptions)
control.publisher(for: .touchDown).sink { [unowned self] _ in
self.animator.stopAnimation(true)
self.view.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
}.store(in: &subscriptions)
control.publisher(for: [.touchUpInside, .touchCancel, .touchUpOutside]).sink { [unowned self] _ in
self.animator.stopAnimation(true)
self.animator = UIViewPropertyAnimator(duration: 0.3, dampingRatio: 0.8) {
self.view.transform = .identity
}
self.animator.startAnimation()
}.store(in: &subscriptions)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.frame = view.bounds
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
subscriptions.cancelAll()
}
private lazy var outlineLayer: CALayer = {
let layer = CALayer()
layer.borderColor = Environment.swatch.yellowFill.cgColor
layer.borderWidth = 2
return layer
}()
private lazy var gradientLayer = Environment.swatch.yellowButtonGradient
}
extension Array where Element == AnyCancellable {
func cancelAll() {
for s in self { s.cancel() }
}
func store<C>(in collection: inout C) where C : RangeReplaceableCollection, C.Element == AnyCancellable {
for s in self { s.store(in: &collection) }
}
}
extension Publisher where Failure == Never {
func assign<Root>(to keyPath: ReferenceWritableKeyPath<Root, Output>, on objects: [Root]) -> [AnyCancellable] {
objects.map { root in
assign(to: keyPath, on: root)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment