diff --git a/VDS/Protocols/SelectorGroupHandlerable.swift b/VDS/Protocols/SelectorGroupHandlerable.swift index 73ba45ca..d9b06fab 100644 --- a/VDS/Protocols/SelectorGroupHandlerable.swift +++ b/VDS/Protocols/SelectorGroupHandlerable.swift @@ -6,14 +6,38 @@ // import Foundation +import UIKit +///MARK: Groups that allow anything selected public protocol SelectorGroupHandlerable: ModelHandlerable, Disabling, Surfaceable where ModelType: SelectorGroupModelable { - associatedtype ModelHandlerType: ModelHandlerable where ModelType.SelectorModelType == ModelHandlerType.ModelType + associatedtype ModelHandlerType: ModelHandlerable where ModelType.SelectorModelType == ModelHandlerType.ModelType, ModelHandlerType: UIControl var selectorViews: [ModelHandlerType] { get set } } extension SelectorGroupHandlerable { + public func findSelectorView(id: UUID) -> ModelHandlerType? { + return selectorViews.first(where: { existingSelectorView in + return existingSelectorView.model.id == id + }) + } + + public func createModelHandler(selector: ModelHandlerType.ModelType) -> ModelHandlerType { + //create view + let newSelectorView = ModelHandlerType(with: selector) + + //add model update to the subscribers + newSelectorView.handlerPublisher() + .sink { [weak self] model in + if let cached = self?.getCachedSelector(viewModel: model), newSelectorView.shouldUpdateView(viewModel: cached) { + self?.replace(viewModel: model) + } + } + .store(in: &subscribers) + + return newSelectorView + } + public func updateSelectors(){ let selectors = model.selectors.compactMap { existing in return existing.copyWith { @@ -42,3 +66,53 @@ extension SelectorGroupHandlerable { } } } + +///MARK: Groups that allow single selections +public protocol SelectorGroupSelectedHandlerable: SelectorGroupHandlerable { + var selectedModel: ModelHandlerType.ModelType? { get set } +} + +extension SelectorGroupSelectedHandlerable { + + public func createModelHandler(selector: ModelHandlerType.ModelType) -> ModelHandlerType { + //create view + let newSelectorView = ModelHandlerType(with: selector) + + //add the selectedPublisher for the change + newSelectorView.publisher(for: .valueChanged) + .sink(receiveValue: { [weak self] control in + guard self?.model.selectors.count ?? 0 > 0 else { return } + self?.didSelect(selector: control.model) + }) + .store(in: &subscribers) + + //add model update to the subscribers + newSelectorView.handlerPublisher() + .sink { [weak self] model in + if let cached = self?.getCachedSelector(viewModel: model), newSelectorView.shouldUpdateView(viewModel: cached) { + self?.replace(viewModel: model) + } + } + .store(in: &subscribers) + + return newSelectorView + } + + public func didSelect(selector: ModelHandlerType.ModelType) { + if var oldSelectedModel = selectedModel { + oldSelectedModel.selected = false + replace(viewModel: oldSelectedModel) + } + + //only select is selected + if selector.selected { + var newSelectedModel = selector + newSelectedModel.selected = true + replace(viewModel: newSelectedModel) + selectedModel = newSelectedModel + } else { + //ensure current value is removed + selectedModel = nil + } + } +} diff --git a/VDS/Protocols/SelectorGroupModelable.swift b/VDS/Protocols/SelectorGroupModelable.swift index 9fd76f4c..3fa327b8 100644 --- a/VDS/Protocols/SelectorGroupModelable.swift +++ b/VDS/Protocols/SelectorGroupModelable.swift @@ -7,7 +7,13 @@ import Foundation +///MARK: Groups that allow anything selected public protocol SelectorGroupModelable: Modelable, FormFieldable, Errorable { - associatedtype SelectorModelType: Modelable where SelectorModelType: FormFieldable + associatedtype SelectorModelType: Modelable where SelectorModelType: FormFieldable & Selectable var selectors: [SelectorModelType] { get set } } + +///MARK: Groups that allow single selections +public protocol SelectorGroupSelectedModelable: SelectorGroupModelable { + var selectedModel: SelectorModelType? { get set } +}