// // Control.swift // VDS // // Created by Matt Bruce on 7/22/22. // import Foundation import UIKit import Combine open class Control: UIControl, ModelHandlerable, ViewProtocol, Resettable { @Published public var model: ModelType private var cancellables = Set() private var shouldUpdate: Bool = false open func set(with model: ModelType) { self.model = model } open func shouldUpdateView(viewModel: ModelType) -> Bool { fatalError("Implement shouldUpdateView") } open func updateView(viewModel: ModelType) { fatalError("Implement updateView") } //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- private var initialSetupPerformed = false @Proxy(\.model.surface) open var surface: Surface @Proxy(\.model.disabled) open var disabled: Bool //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- required public init(with model: ModelType) { self.model = model super.init(frame: .zero) initialSetup() set(with: model) } public required init?(coder: NSCoder) { self.model = ModelType.init() super.init(coder: coder) initialSetup() } //-------------------------------------------------- // MARK: - Setup //-------------------------------------------------- public func initialSetup() { if !initialSetupPerformed { initialSetupPerformed = true //setup shouldUpdate $model.sink { [weak self] viewModel in guard let self = self else { return } let s = self.shouldUpdateView(viewModel: viewModel) print("shouldUpdate - \(Self.self): \(s)") self.shouldUpdate = s }.store(in: &cancellables) //setup viewUpdate $model.debounce(for: .seconds(Constants.ModelStateDebounce), scheduler: RunLoop.main).sink { [weak self] viewModel in guard let self = self else { return } if self.shouldUpdate { self.updateView(viewModel: viewModel) self.shouldUpdate = false print("didUpdate - \(Self.self)") } }.store(in: &cancellables) setup() } } open func reset() { backgroundColor = .clear } // MARK: - ViewProtocol /// Will be called only once. open func setup() { translatesAutoresizingMaskIntoConstraints = false insetsLayoutMarginsFromSafeArea = false } }