// // RadioButtonGroup.swift // VDS // // Created by Matt Bruce on 8/8/22. // import Foundation import UIKit public protocol SelectorGroupModel: Modelable, FormFieldable { associatedtype SelectorType: SelectorModel var selectors: [SelectorType] { get set } } public struct DefaultSelectorGroupModel: SelectorGroupModel { public var inputId: String? public var value: AnyHashable? public var surface: Surface = .light public var disabled: Bool = false public var selectors: [SelectorType] public init() { selectors = [] } public init(selectors: [SelectorType]){ self.selectors = selectors } } open class SelectorGroup, SelectorHandlerType: SelectorBase>: View, Changable { public var selectorViews: [SelectorHandlerType] = [] public var selectedModel: SelectorType? public var onChange: Blocks.ActionBlock? //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- private var mainStackView: UIStackView = { let stackView = UIStackView() stackView.translatesAutoresizingMaskIntoConstraints = false stackView.alignment = .top stackView.axis = .vertical stackView.spacing = 10 return stackView }() //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- override public var disabled: Bool { didSet { let selectors = model.selectors.compactMap { existing in return updated(existing){ $0.disabled = disabled } } model.selectors = selectors } } override public var surface: Surface { didSet { let selectors = model.selectors.compactMap { existing in return updated(existing){ $0.surface = surface } } model.selectors = selectors } } open override func setup() { super.setup() isAccessibilityElement = true accessibilityTraits = .button addSubview(mainStackView) mainStackView.topAnchor.constraint(equalTo: topAnchor).isActive = true mainStackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true mainStackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true mainStackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true } open override func shouldUpdateView(viewModel: ModelType) -> Bool { return true } open override func updateView(viewModel: ModelType) { print("Selector Group update:") func findSelectorView(inputId: String) -> SelectorHandlerType? { return selectorViews.first(where: { existingSelectorView in return existingSelectorView.model.inputId == inputId }) } for selectorModel in viewModel.selectors { //see if view is there for the model if let inputId = selectorModel.inputId, let foundSelectorView = findSelectorView(inputId: inputId) { foundSelectorView.set(with: selectorModel) } else { //create view let newSelectorView = SelectorHandlerType(with: selectorModel) newSelectorView.didSelect = {[weak self] (inputId) in guard let self else { return } self.didSelect(selected: selectorModel) } self.selectorViews.append(newSelectorView) mainStackView.addArrangedSubview(newSelectorView) } } } open func didSelect(selected: SelectorType) { } }