// // RadioButtonGroup.swift // VDS // // Created by Matt Bruce on 8/8/22. // import Foundation import UIKit public protocol SelectorGroup: Modelable { associatedtype SelectorType: SelectorModel var models: [SelectorType] { get set } } public struct RadioButtonGroupModel: SelectorGroup, FormFieldable{ public var inputId: String? public var value: AnyHashable? public var surface: Surface = .light public var disabled: Bool = false public var models: [DefaultRadioButtonModel] public init() { models = [] } public init(models: [DefaultRadioButtonModel]){ self.models = models } } public class RadioButtonGroup: View, Changable { public var radioButtons: [RadioButton] = [] public var selectedView: RadioButton? 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 models = model.models.compactMap { existing in return updated(existing){ $0.disabled = disabled } } model.models = models } } override public var surface: Surface { didSet { let models = model.models.compactMap { existing in return updated(existing){ $0.surface = surface } } model.models = models } } 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 } public override func onStateChange(viewModel: RadioButtonGroupModel) { super.onStateChange(viewModel: viewModel) for radioButtonModel in viewModel.models { let radioButton = radioButtons.first(where: { existingRadioButton in return existingRadioButton.model.inputId == radioButtonModel.inputId && radioButtonModel.inputId != nil }) //found view if let radioButton = radioButton { radioButton.set(with: radioButtonModel) } else { //create view let newRadioButton = RadioButton(with: radioButtonModel) newRadioButton.selectorController = self self.radioButtons.append(newRadioButton) mainStackView.addArrangedSubview(newRadioButton) } } } //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- public convenience init() { self.init(with: ModelType()) } required public init(with model: ModelType) { super.init(with: model) } required public init?(coder: NSCoder) { super.init(with: ModelType()) } //-------------------------------------------------- // MARK: - Delegate //-------------------------------------------------- public func didSelect(selector: RadioButton) { selectedView?.isSelected = false selector.isSelected = true selectedView = selector } }