diff --git a/VDSSample/Protocols/PickerBase.swift b/VDSSample/Protocols/PickerBase.swift index cdb46f2..4e19de4 100644 --- a/VDSSample/Protocols/PickerBase.swift +++ b/VDSSample/Protocols/PickerBase.swift @@ -38,6 +38,7 @@ class PickerBase: NSObject, PickerViewable, UIPicker } func pickerView( _ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + guard row - 1 >= 0 else { return } onPickerDidSelect?(items[row-1]) pickerView.isHidden = true } diff --git a/VDSSample/ViewControllers/CheckboxViewController.swift b/VDSSample/ViewControllers/CheckboxViewController.swift index 4fac3c4..ed51f29 100644 --- a/VDSSample/ViewControllers/CheckboxViewController.swift +++ b/VDSSample/ViewControllers/CheckboxViewController.swift @@ -11,8 +11,6 @@ import VDS import VDSColorTokens import Combine - - class CheckboxViewController: ModelViewController, StoryboardInitable { enum PickerType { @@ -42,25 +40,29 @@ class CheckboxViewController: ModelViewController, Storyb checkbox.trailingAnchor.constraint(equalTo: checkboxContainerView.trailingAnchor, constant: 10).isActive = true view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:)))) setupPicker() - createModel() - setupBinding() + setupModel() } - func createModel() { - var model = DefaultCheckboxModel() - model.labelText = "Terms and conditions" - model.childText = "I agree to Verizon's terms and conditions click here" - model.childTextAttributes = [ + func setupModel() { + var defaultModel = DefaultCheckboxModel() + defaultModel.labelText = "Terms and conditions" + defaultModel.childText = "I agree to Verizon's terms and conditions click here" + defaultModel.childTextAttributes = [ LabelAttributeUnderline(location: 11, length: 10), LabelAttributeStrikeThrough(location: 22, length: 5), LabelAttributeColor(location: 31, length: 10, color: UIColor.blue.hexString!), LabelAttributeActionModel(location: 31, length: 10){ print("clicked on the word 'conditions'") }, LabelAttributeFont(location: 2, length: 5, style: .BoldTitleLarge, color: UIColor.red.hexString!) ] - model.errorText = "Error Text" - - checkbox.set(with: model) + defaultModel.errorText = "Error Text" + model = defaultModel + checkbox + .handlerPublisher() + .sink { [weak self] viewModel in + self?.model = viewModel + }.store(in: &subscribers) + //setup UI surfaceLabel.text = model.surface.rawValue disabledSwitch.isOn = model.selected @@ -71,21 +73,9 @@ class CheckboxViewController: ModelViewController, Storyb } - func setupBinding() { - - checkbox.createBinding(with: model, storeIn: &subscribers) - - //print out on subject changes - model - .debounce(for: .seconds(Constants.ModelStateDebounce), scheduler: RunLoop.main) - .sink { [weak self] updatedModel in - self?.showErrorSwitch.isOn = updatedModel.hasError - print("CheckboxViewController local hasError: \(self?.model.value.hasError)") - print("CheckboxViewController hasError: \(updatedModel.hasError)") - print("CheckboxViewController local selected: \(self?.model.value.selected)") - print("CheckboxViewController selected: \(updatedModel.selected)") - } - .store(in: &subscribers) + override func updateView(viewModel: DefaultCheckboxModel) { + print("\(Self.self) updateView(viewModel)") + checkbox.set(with: viewModel) } @IBAction func disabledChanged(_ sender: UISwitch) { diff --git a/VDSSample/ViewControllers/ModelViewController.swift b/VDSSample/ViewControllers/ModelViewController.swift index 244c784..f45f32b 100644 --- a/VDSSample/ViewControllers/ModelViewController.swift +++ b/VDSSample/ViewControllers/ModelViewController.swift @@ -10,7 +10,7 @@ import UIKit import Combine import VDS -public class ModelViewController: UIViewController { +public class ModelViewController: UIViewController, ModelHandlerable, Initable { deinit { print("\(Self.self) deinit") } @@ -18,7 +18,8 @@ public class ModelViewController: UIViewController { //-------------------------------------------------- // MARK: - Combine Properties //-------------------------------------------------- - public var model = CurrentValueSubject(ModelType()) + @Published public var model: ModelType = ModelType() + public var modelPublisher: Published.Publisher { $model } public var subscribers = Set() //-------------------------------------------------- @@ -26,10 +27,10 @@ public class ModelViewController: UIViewController { //-------------------------------------------------- private var initialSetupPerformed = false - @Proxy(\.model.value.surface) + @Proxy(\.model.surface) open var surface: Surface - @Proxy(\.model.value.disabled) + @Proxy(\.model.disabled) open var disabled: Bool //-------------------------------------------------- @@ -63,17 +64,7 @@ public class ModelViewController: UIViewController { public func initialSetup() { if !initialSetupPerformed { initialSetupPerformed = true - model - .filter { [weak self] viewModel in - return self?.shouldUpdateView(viewModel: viewModel) ?? false - - } - .debounce(for: .seconds(Constants.ModelStateDebounce), scheduler: RunLoop.main) - .sink { [weak self] viewModel in - self?.updateView() - - } - .store(in: &subscribers) + setupUpdateView() setup() } } @@ -82,12 +73,6 @@ public class ModelViewController: UIViewController { open func shouldUpdateView(viewModel: ModelType) -> Bool { true } - open func updateView() {} - - open func set(with model: ModelType) { - if shouldUpdateView(viewModel: model){ - self.model.send(model) - } - } + open func updateView(viewModel: ModelType) {} } diff --git a/VDSSample/ViewControllers/RadioButtonViewController.swift b/VDSSample/ViewControllers/RadioButtonViewController.swift index e3815a1..29a4a94 100644 --- a/VDSSample/ViewControllers/RadioButtonViewController.swift +++ b/VDSSample/ViewControllers/RadioButtonViewController.swift @@ -11,7 +11,7 @@ import VDS import VDSColorTokens import Combine -class RadioButtonViewController: UIViewController, StoryboardInitable { +class RadioButtonViewController: ModelViewController, StoryboardInitable { deinit { print("\(Self.self) deinit") } @@ -32,8 +32,6 @@ class RadioButtonViewController: UIViewController, StoryboardInitable { @IBOutlet weak var showErrorSwitch: UISwitch! var radioButtonGroup = RadioButtonGroup() - public var model = DefaultRadioButtonGroupModel() - public var subscribers = Set() override func viewDidLoad() { super.viewDidLoad() @@ -45,12 +43,11 @@ class RadioButtonViewController: UIViewController, StoryboardInitable { radioButtonGroup.bottomAnchor.constraint(equalTo: componentContainerView.bottomAnchor, constant: -20).isActive = true radioButtonGroup.trailingAnchor.constraint(equalTo: componentContainerView.trailingAnchor, constant: 10).isActive = true setupPicker() - - createModel() - setupBinding() + setupModel() } - func createModel(){ + func setupModel(){ + var defaultModel = DefaultRadioButtonGroupModel() var model1 = DefaultRadioButtonModel() model1.value = "model 1 Value" model1.labelText = "Terms and conditions" @@ -66,34 +63,32 @@ class RadioButtonViewController: UIViewController, StoryboardInitable { var model2 = DefaultRadioButtonModel() model2.value = "model 2 Value" model2.childText = "Radio Sample 2" - model.selectors = [model1, model2] + defaultModel.selectors = [model1, model2] + model = defaultModel + //update the model + radioButtonGroup + .handlerPublisher() + .sink { [weak self] updatedModel in + self?.model = updatedModel + self?.showErrorSwitch.isOn = updatedModel.hasError + self?.disabledSwitch.isOn = updatedModel.disabled + } + .store(in: &subscribers) + //set UI values surfaceLabel.text = model.surface.rawValue disabledSwitch.isOn = model.disabled showErrorSwitch.isOn = model.hasError labelTextField.text = model1.labelText childTextField.text = model1.childText - - radioButtonGroup.set(with: model) } - func setupBinding() { - //update the model - //print out on subject changes - radioButtonGroup.handlerPublisher() - .sink { [weak self] updatedModel in - print("before RadioButtonViewController local selectedModel Id: \(self?.model.selectedModel?.id)") - self?.model = updatedModel - self?.showErrorSwitch.isOn = updatedModel.hasError - print("RadioButtonViewController hasError: \(updatedModel.hasError)") - - if let selectedModel = updatedModel.selectedModel { - print("RadioButtonViewController selectedModel Id: \(selectedModel.id)") - print("after RadioButtonViewController local selectedModel Id: \(self?.model.selectedModel?.id)") - } - } - .store(in: &subscribers) + override func updateView(viewModel: DefaultRadioButtonGroupModel) { + print("\(Self.self) updateView(viewModel)") + showErrorSwitch.isOn = viewModel.hasError + disabledSwitch.isOn = viewModel.disabled + radioButtonGroup.set(with: viewModel) } var radioButton: RadioButton? { diff --git a/VDSSample/ViewControllers/TemplateViewController.swift b/VDSSample/ViewControllers/TemplateViewController.swift index b3ae02d..40bbbe0 100644 --- a/VDSSample/ViewControllers/TemplateViewController.swift +++ b/VDSSample/ViewControllers/TemplateViewController.swift @@ -54,7 +54,7 @@ struct TestLayoutModel: Modelable { } } -class TemplateViewController: ModelViewController, Initable { +class TemplateViewController: ModelViewController { enum ModelHandlerError: Error { case cantFind } @@ -76,48 +76,33 @@ class TemplateViewController: ModelViewController, Initable { stackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20).isActive = true stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20).isActive = true stackView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 10).isActive = true - -// //CurrentValueSubject -// let checkSubject = CurrentValueSubject(model.value.checkbox) -// checkbox.createBinding(with: checkSubject, storeIn: &subscribers) -// checkSubject.sink { [weak self] checkModel in -// self?.model.value.checkbox = checkModel -// }.store(in: &subscribers) -// stackView.addArrangedSubview(checkbox) -// -// let radioSubject = CurrentValueSubject(model.value.radioButtonGroup) -// radioButtonGroup.createBinding(with: radioSubject, storeIn: &subscribers) -// radioSubject.sink { [weak self] radioGroupModel in -// self?.model.value.radioButtonGroup = radioGroupModel -// }.store(in: &subscribers) -// stackView.addArrangedSubview(radioButtonGroup) //Publisher way checkbox.handlerPublisher() .sink { [weak self] checkModel in - self?.model.value.checkbox = checkModel + self?.model.checkbox = checkModel } .store(in: &subscribers) stackView.addArrangedSubview(checkbox) radioButtonGroup.handlerPublisher() .sink { [weak self] radioGroupModel in - self?.model.value.radioButtonGroup = radioGroupModel + self?.model.radioButtonGroup = radioGroupModel } .store(in: &subscribers) stackView.addArrangedSubview(radioButtonGroup) - checkbox.set(with: model.value.checkbox) - radioButtonGroup.set(with: model.value.radioButtonGroup) + checkbox.set(with: model.checkbox) + radioButtonGroup.set(with: model.radioButtonGroup) } - override func updateView() { - print("updateView Called") - checkbox.set(with: model.value.checkbox) - radioButtonGroup.set(with: model.value.radioButtonGroup) + override func updateView(viewModel: ModelType) { + print("\(Self.self) updateView(viewModel)") + checkbox.set(with: model.checkbox) + radioButtonGroup.set(with: model.radioButtonGroup) print("radioButtonGroup selected: \(radioButtonGroup.selectedModel?.id)") - print("model.value.radioButtonGroup selected: \(model.value.radioButtonGroup.selectedModel?.id)") + print("model.value.radioButtonGroup selected: \(model.radioButtonGroup.selectedModel?.id)") } }