From a55bea38deccbba47f03f6407af35aafda4fcb2c Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 10 Aug 2022 10:11:03 -0500 Subject: [PATCH] updated to selector base Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 7 +- VDS/Components/RadioButton/RadioButton.swift | 10 +-- .../SelectorBase/SelectorBase.swift | 2 +- .../SelectorGroup.swift} | 89 +++++++++++-------- 4 files changed, 60 insertions(+), 48 deletions(-) rename VDS/Components/{RadioButton/RadioButtonGroup.swift => SelectorBase/SelectorGroup.swift} (53%) diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index e4b1d491..81afa155 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -38,6 +38,7 @@ EA3362452892F9130071C351 /* Labelable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3362442892F9130071C351 /* Labelable.swift */; }; EA33624728931B050071C351 /* Initable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA33624628931B050071C351 /* Initable.swift */; }; EA3C3B4C2894823E000CA526 /* AnyProxy-PropertyWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3C3B4B2894823E000CA526 /* AnyProxy-PropertyWrapper.swift */; }; + EAB1D29428A3ECF700DAE764 /* SelectorGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F13028A17FAB00B287F5 /* SelectorGroup.swift */; }; EAF7F0952899861000B287F5 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0932899861000B287F5 /* Checkbox.swift */; }; EAF7F0962899861000B287F5 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0942899861000B287F5 /* CheckboxModel.swift */; }; EAF7F09A2899B17200B287F5 /* CATransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0992899B17200B287F5 /* CATransaction.swift */; }; @@ -140,8 +141,8 @@ EAF7F11628A1475A00B287F5 /* RadioButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioButtonModel.swift; sourceTree = ""; }; EAF7F12B28A1617600B287F5 /* SelectorBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorBase.swift; sourceTree = ""; }; EAF7F12E28A1619600B287F5 /* SelectorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorModel.swift; sourceTree = ""; }; + EAF7F13028A17FAB00B287F5 /* SelectorGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorGroup.swift; sourceTree = ""; }; EAF7F13228A2A16500B287F5 /* LabelAttributeAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeAttachment.swift; sourceTree = ""; }; - EAF7F13028A17FAB00B287F5 /* RadioButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonGroup.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -364,7 +365,6 @@ EAF7F11428A1470D00B287F5 /* RadioButton */ = { isa = PBXGroup; children = ( - EAF7F13028A17FAB00B287F5 /* RadioButtonGroup.swift */, EAF7F11528A1475A00B287F5 /* RadioButton.swift */, EAF7F11628A1475A00B287F5 /* RadioButtonModel.swift */, ); @@ -375,6 +375,7 @@ isa = PBXGroup; children = ( EAF7F12B28A1617600B287F5 /* SelectorBase.swift */, + EAF7F13028A17FAB00B287F5 /* SelectorGroup.swift */, EAF7F12E28A1619600B287F5 /* SelectorModel.swift */, ); path = SelectorBase; @@ -496,13 +497,13 @@ EA3362322891F2ED0071C351 /* FontStyles.swift in Sources */, EAF7F0B5289C126F00B287F5 /* UILabel.swift in Sources */, EAF7F0A6289B0CE000B287F5 /* Resetable.swift in Sources */, + EAB1D29428A3ECF700DAE764 /* SelectorGroup.swift in Sources */, EA3361C328902D960071C351 /* Toggle.swift in Sources */, EAF7F12C28A1617600B287F5 /* SelectorBase.swift in Sources */, EAF7F0A0289AB7EC00B287F5 /* View.swift in Sources */, EAF7F11828A1475A00B287F5 /* RadioButtonModel.swift in Sources */, EAF7F12F28A1619600B287F5 /* SelectorModel.swift in Sources */, EA3362402892EF6C0071C351 /* Label.swift in Sources */, - EAF7F13128A17FAB00B287F5 /* RadioButtonGroup.swift in Sources */, EAF7F0B3289B1ADC00B287F5 /* LabelAttributeAction.swift in Sources */, EA33622E2891EA3C0071C351 /* DispatchQueue+Once.swift in Sources */, EAF7F0AF289B144C00B287F5 /* LabelAttributeUnderline.swift in Sources */, diff --git a/VDS/Components/RadioButton/RadioButton.swift b/VDS/Components/RadioButton/RadioButton.swift index db94ec6e..478bc7db 100644 --- a/VDS/Components/RadioButton/RadioButton.swift +++ b/VDS/Components/RadioButton/RadioButton.swift @@ -9,21 +9,21 @@ import Foundation import UIKit import VDSColorTokens import VDSFormControlsTokens -import Combine public class RadioButton: RadioButtonBase{ - public var selectorController: RadioButtonGroup? - //this is where the code would go for the controller public override func toggleAndAction() { - if let selectorController = selectorController { - selectorController.didSelect(selector: self) + if let didSelect = self.didSelect { + didSelect(model.inputId) } else { super.toggleAndAction() } } } +public class RadioButtonGroupModel: SelectorGroupModelBase {} +public class RadioButtonGroup: SelectorGroupBase {} + open class RadioButtonBase: SelectorBase { //-------------------------------------------------- diff --git a/VDS/Components/SelectorBase/SelectorBase.swift b/VDS/Components/SelectorBase/SelectorBase.swift index b75d2791..0625a613 100644 --- a/VDS/Components/SelectorBase/SelectorBase.swift +++ b/VDS/Components/SelectorBase/SelectorBase.swift @@ -65,7 +65,7 @@ open class SelectorBase: Control, Changable view.translatesAutoresizingMaskIntoConstraints = false return view }() - + public var didSelect: ((String?) -> ())? public var onChange: Blocks.ActionBlock? @Proxy(\.model.id) diff --git a/VDS/Components/RadioButton/RadioButtonGroup.swift b/VDS/Components/SelectorBase/SelectorGroup.swift similarity index 53% rename from VDS/Components/RadioButton/RadioButtonGroup.swift rename to VDS/Components/SelectorBase/SelectorGroup.swift index 50d622a8..9f6c063a 100644 --- a/VDS/Components/RadioButton/RadioButtonGroup.swift +++ b/VDS/Components/SelectorBase/SelectorGroup.swift @@ -8,27 +8,27 @@ import Foundation import UIKit -public protocol SelectorGroup: Modelable { + +public protocol SelectorGroupModel: Modelable, FormFieldable { associatedtype SelectorType: SelectorModel - var models: [SelectorType] { get set } + var selectors: [SelectorType] { get set } } -public struct RadioButtonGroupModel: SelectorGroup, FormFieldable{ +open class SelectorGroupModelBase: SelectorGroupModel{ 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 var selectors: [SelectorType] + required public init() { selectors = [] } + public init(selectors: [SelectorType]){ + self.selectors = selectors } } -public class RadioButtonGroup: View, Changable { - - public var radioButtons: [RadioButton] = [] - public var selectedView: RadioButton? +open class SelectorGroupBase>: View>, Changable { + public var selectorViews: [SelectorHandlerType] = [] + public var selectedView: SelectorHandlerType? public var onChange: Blocks.ActionBlock? //-------------------------------------------------- @@ -42,85 +42,96 @@ public class RadioButtonGroup: View, Changable { stackView.spacing = 10 return stackView }() - + //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- override public var disabled: Bool { didSet { - let models = model.models.compactMap { existing in + let selectors = model.selectors.compactMap { existing in return updated(existing){ $0.disabled = disabled } } - model.models = models + model.selectors = selectors } } - + override public var surface: Surface { didSet { - let models = model.models.compactMap { existing in + let selectors = model.selectors.compactMap { existing in return updated(existing){ $0.surface = surface } } - model.models = models + 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 } - - 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 + + open override func shouldUpdateView(viewModel: ModelType) -> Bool { + return true + } + + open override func updateView(viewModel: ModelType) { + func findSelectorView(inputId: String) -> SelectorHandlerType? { + return selectorViews.first(where: { existingSelectorView in + return existingSelectorView.model.inputId == inputId }) - - //found view - if let radioButton = radioButton { - radioButton.set(with: radioButtonModel) + } + + 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 newRadioButton = RadioButton(with: radioButtonModel) - newRadioButton.selectorController = self - self.radioButtons.append(newRadioButton) - mainStackView.addArrangedSubview(newRadioButton) + let newSelectorView = SelectorHandlerType(with: selectorModel) + newSelectorView.didSelect = {[weak self] (inputId) in + guard let self else { return } + self.selectedView?.isSelected = false + if let inputId = selectorModel.inputId, let selector = findSelectorView(inputId: inputId) { + selector.isSelected = true + self.selectedView = selector + } + } + self.selectorViews.append(newSelectorView) + mainStackView.addArrangedSubview(newSelectorView) } } } - + //-------------------------------------------------- // 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) { + public func didSelect(selector: SelectorHandlerType) { selectedView?.isSelected = false selector.isSelected = true selectedView = selector