Skip to content

Instantly share code, notes, and snippets.

@dmpv
Created July 22, 2020 15:43
Show Gist options
  • Save dmpv/aee8a0436d29c63cd6f15bdce1c1a187 to your computer and use it in GitHub Desktop.
Save dmpv/aee8a0436d29c63cd6f15bdce1c1a187 to your computer and use it in GitHub Desktop.
Component Templates
import Foundation
import UIKit
import RxSwift
import SnapKit
final class TemplateView: UIView, StatefulComponent {
var state: State? {
didSet { stateDidChange(from: oldValue) }
}
var handlers = Handlers() {
didSet { handlersDidChange() }
}
var bindBag = DisposeBag()
// private var subview: Subview!
// private var component: Component!
private var pendingLayoutChange: (from: Layout?, to: Layout?)?
init() {
super.init(frame: .zero)
setupSubviews()
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError()
}
private func setupSubviews() {
// ...setup self...
// layoutMargins =
// subview = Subview()
// ...setup subview...
// addSubview(subview)
// component = components.makeComponent()
// ...setup component...
// addSubview(component.view)
}
private func stateDidChange(from oldState: State?) {
guard state != oldState else { return }
// ...set substates...
layoutDidChange(from: oldState?.layout)
appearanceDidChange(from: oldState?.appearance)
}
private func layoutDidChange(from oldLayout: Layout?) {
guard state?.layout != oldLayout else { return }
pendingLayoutChange = (from: oldLayout, to: state?.layout)
setNeedsUpdateConstraints()
}
private func appearanceDidChange(from oldAppearance: Appearance?) {
guard state?.appearance != oldAppearance else { return }
guard let appearance = state?.appearance else { /* handle nil if needed */ return }
// applying { ... }
// subview.applying { ... }
}
private func handlersDidChange() {}
public override func updateConstraints() {
defer {
pendingLayoutChange = nil
super.updateConstraints()
}
guard let pendingLayoutChange = pendingLayoutChange else { return }
guard let _ = pendingLayoutChange.to else { /* handle nil if needed */ return }
// ...remake (update) snapkit constraints...
}
}
extension TemplateView {
struct State: Equatable {
// var title: String
// var subcomponent: Subcomponent.State
var layout = Layout()
var appearance: Appearance
}
struct Layout: Equatable {
// ...props...
}
struct Appearance: Equatable {
// var backgroundColor: UIColor
}
struct Handlers {
// var onSmth: ...some closure...
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment