// // Control.swift // VDS // // Created by Matt Bruce on 7/22/22. // import Foundation import UIKit import Combine open class View: UIView, ModelHandlerable, ViewProtocol, Resettable { @Published public var model: ModelType public var cancellables = Set() 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() { self.model = ModelType() super.init(frame: .zero) initialSetup() } public required init(with model: ModelType) { self.model = model super.init(frame: .zero) initialSetup() } public override init(frame: CGRect) { self.model = ModelType() super.init(frame: .zero) initialSetup() } public required init?(coder: NSCoder) { self.model = ModelType.init() super.init(coder: coder) initialSetup() } //-------------------------------------------------- // MARK: - Setup //-------------------------------------------------- public func initialSetup() { if !initialSetupPerformed { initialSetupPerformed = true //setup viewUpdate $model.filter { viewModel in return self.shouldUpdateView(viewModel: viewModel) }.debounce(for: .seconds(Constants.ModelStateDebounce), scheduler: RunLoop.main).sink { [weak self] viewModel in guard let self = self else { return } self.updateView(viewModel: viewModel) }.store(in: &cancellables) setup() } } open func reset() { backgroundColor = .clear } // MARK: - ViewProtocol open func updateView(_ size: CGFloat) { } /// Will be called only once. open func setup() { translatesAutoresizingMaskIntoConstraints = false insetsLayoutMarginsFromSafeArea = false } }