// // RadioButtonGroup.swift // VDS // // Created by Matt Bruce on 8/11/22. // import Foundation import UIKit public class RadioButtonGroup: Control, SelectorGroupSelectedModelHandlerable, Changable { public typealias ModelHandlerType = RadioButton //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- public var selectorViews: [ModelHandlerType] = [] @Proxy(\.model.selectedModel) public var selectedModel: ModelHandlerType.ModelType? { didSet{ if hasError, selectedModel != nil { hasError = false } } } public var hasError: Bool { get { model.hasError } set { var newHasError = newValue if selectedModel != nil, newHasError { newHasError = false } let selectors = model.selectors.compactMap { existing in return existing.copyWith { $0.hasError = newHasError } } model.hasError = newHasError model.selectors = selectors } } public var onChange: Blocks.ActionBlock? //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- private var mainStackView: UIStackView = { return UIStackView().with { $0.translatesAutoresizingMaskIntoConstraints = false $0.alignment = .fill $0.distribution = .fillProportionally $0.axis = .vertical $0.spacing = 10 } }() //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- override public var disabled: Bool { didSet { updateSelectors() } } override public var surface: Surface { didSet { updateSelectors() } } 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 { let update = viewModel.selectedModel?.inputId != model.selectedModel?.inputId || viewModel.selectors.count != model.selectors.count || viewModel.hasError != model.hasError || viewModel.surface != model.surface || viewModel.disabled != model.disabled return update } open override func updateView(viewModel: ModelType) { for selectorModel in viewModel.selectors { //see if view is there for the model if let foundSelectorView = findSelectorView(inputId: selectorModel.inputId) { foundSelectorView.set(with: selectorModel) } else { //create view let newSelectorView = createModelHandler(selector: selectorModel) self.selectorViews.append(newSelectorView) mainStackView.addArrangedSubview(newSelectorView) } } } }