From 5337f3084300609b6697db224ab5d17093b3a158 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 30 Sep 2022 09:45:03 -0500 Subject: [PATCH] refactored picker logic Signed-off-by: Matt Bruce --- VDSSample/Protocols/PickerBase.swift | 132 +++++++++++------- .../ViewControllers/BadgeViewController.swift | 78 +++-------- .../ButtonViewController.swift | 74 +++------- .../CheckBoxGroupViewController.swift | 35 +---- .../CheckboxViewController.swift | 36 +---- .../ViewControllers/LabelViewController.swift | 77 +++------- .../RadioBoxGroupViewController.swift | 38 +---- .../RadioButtonViewController.swift | 42 ++---- .../RadioSwatchGroupViewController.swift | 39 +----- .../ToggleViewController.swift | 71 +++------- 10 files changed, 197 insertions(+), 425 deletions(-) diff --git a/VDSSample/Protocols/PickerBase.swift b/VDSSample/Protocols/PickerBase.swift index 605f5c8..7ee86f8 100644 --- a/VDSSample/Protocols/PickerBase.swift +++ b/VDSSample/Protocols/PickerBase.swift @@ -8,20 +8,73 @@ import Foundation import UIKit import VDS +import Combine -protocol PickerViewable { +public struct PickerType : RawRepresentable, Equatable, Hashable { + public var rawValue: String + public init(_ rawValue: String) { + self.rawValue = rawValue + } + public init(rawValue: String) { + self.rawValue = rawValue + } + + public static var surface = PickerType(rawValue: "surface") + public static var textPosition = PickerType(rawValue: "textPosition") + public static var textSize = PickerType(rawValue: "textSize") + public static var fontCategory = PickerType(rawValue: "fontCategory") +} + +protocol PickerViewable: UIPickerViewDataSource, UIPickerViewDelegate, Hashable { associatedtype EnumType: RawRepresentable var items: [EnumType] { get set } var onPickerDidSelect: ((EnumType) -> Void)? { get set } } -class PickerBase: NSObject, PickerViewable, UIPickerViewDataSource, UIPickerViewDelegate { - var items: [EnumType] +class PickerSelectorView: UIStackView, PickerViewable { + private weak var picker: UIPickerView? + fileprivate var selectedIndex = 0 + private var subscribers = Set() + private var label = UILabel() + private var button = UIButton(type: .system).with { instance in + instance.configuration = .filled() + instance.setTitle("Select", for: .normal) + } + + var text: String = "" { + didSet { + label.text = text + } + } + var items: [EnumType] { + didSet { selectedIndex = 0 } + } var onPickerDidSelect: ((EnumType) -> Void)? - init(items: [EnumType]) { + init(title: String, picker: UIPickerView? = nil, items: [EnumType]) { + self.picker = picker self.items = items - super.init() + super.init(frame: .zero) + + self.axis = .horizontal + self.distribution = .fillEqually + self.alignment = .fill + label.text = title + addArrangedSubview(label) + addArrangedSubview(button) + button + .publisher(for: .touchUpInside) + .sink { [weak self] _ in + self?.picker?.delegate = self + self?.picker?.dataSource = self + self?.picker?.reloadAllComponents() + self?.picker?.selectRow(self?.selectedIndex ?? 0, inComponent: 0, animated: false) + self?.picker?.isHidden = false + }.store(in: &subscribers) + } + + required init(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") } func numberOfComponents(in pickerView: UIPickerView) -> Int { @@ -39,32 +92,15 @@ class PickerBase: NSObject, PickerViewable, UIPicker func pickerView( _ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { guard row - 1 >= 0 else { return } + selectedIndex = row onPickerDidSelect?(items[row-1]) pickerView.isHidden = true } } -class PickerSelectorView: UIStackView { - private var label = UILabel() - var button = UIButton(type: .system).with { instance in - instance.configuration = .filled() - instance.setTitle("Select", for: .normal) - } - - var text: String = "" { - didSet { - label.text = text - } - } - - init(title: String){ - super.init(frame: .zero) - self.axis = .horizontal - self.distribution = .fillEqually - self.alignment = .fill - label.text = title - addArrangedSubview(label) - addArrangedSubview(button) +class SurfacePickerSelectorView: PickerSelectorView{ + init(picker: UIPickerView? = nil){ + super.init(title: "light", picker: picker, items: [.light, .dark]) } required init(coder: NSCoder) { @@ -72,34 +108,32 @@ class PickerSelectorView: UIStackView { } } -class SurfacePicker: PickerBase { - init(){ - super.init(items: [.light, .dark]) +class TextPositionPickerSelectorView: PickerSelectorView{ + init(picker: UIPickerView? = nil){ + super.init(title: "left", picker: picker, items: [.left, .right]) + } + + required init(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") } } -class TextPositionPicker: PickerBase { - init(){ - super.init(items: [.left, .right]) +class TextSizePickerSelectorView: PickerSelectorView{ + init(title: String, picker: UIPickerView? = nil){ + super.init(title: title, picker: picker, items: [.small, .large]) + } + + required init(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") } } -class TextSizePicker: PickerBase { - init(){ - super.init(items: [.small, .large]) +class FontCategoryPickerSelectorView: PickerSelectorView{ + init(title: String, picker: UIPickerView? = nil){ + super.init(title: title, picker: picker, items: TypographicalStyle.FontCategory.allCases) + } + + required init(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") } } - -class FontCategoryPicker: PickerBase { - init(){ - super.init(items: TypographicalStyle.FontCategory.allCases) - } -} - -class UsePicker: PickerBase { - init(){ - super.init(items: [.primary, .secondary]) - } -} - - diff --git a/VDSSample/ViewControllers/BadgeViewController.swift b/VDSSample/ViewControllers/BadgeViewController.swift index a0d39cf..3ae4084 100644 --- a/VDSSample/ViewControllers/BadgeViewController.swift +++ b/VDSSample/ViewControllers/BadgeViewController.swift @@ -12,11 +12,7 @@ import VDSColorTokens import Combine class BadgeViewController: ModelScrollViewController { - - enum PickerType { - case surface, fillColor, numberOfLines - } - + enum NumberOfLines: String, CaseIterable { case unlimited case one @@ -40,10 +36,23 @@ class BadgeViewController: ModelScrollViewController { } } } + + lazy var fillColorPickerSelectorView = { + PickerSelectorView(title: "red", + picker: self.picker, + items: BadgeFillColor.allCases) + }() + + lazy var numberOfLinesPickerSelectorView = { + PickerSelectorView(title: "one", + picker: self.picker, + items: NumberOfLines.allCases) + }() + + lazy var surfacePickerSelectorView = { + SurfacePickerSelectorView(picker: self.picker) + }() - var fillColorPickerSelectorView = PickerSelectorView(title: "red") - var numberOfLinesPickerSelectorView = PickerSelectorView(title: "one") - var surfacePickerSelectorView = PickerSelectorView(title: "light") var textField = TextField() var maxWidthTextField = TextField() var badge = Badge() @@ -85,25 +94,6 @@ class BadgeViewController: ModelScrollViewController { } self?.badge.maxWidth = float }.store(in: &subscribers) - - surfacePickerSelectorView.button - .publisher(for: .touchUpInside) - .sink { [weak self] _ in - self?.pickerType = .surface - }.store(in: &subscribers) - - fillColorPickerSelectorView.button - .publisher(for: .touchUpInside) - .sink { [weak self] _ in - self?.pickerType = .fillColor - }.store(in: &subscribers) - - numberOfLinesPickerSelectorView.button - .publisher(for: .touchUpInside) - .sink { [weak self] _ in - self?.pickerType = .numberOfLines - }.store(in: &subscribers) - } func setupModel() { @@ -130,49 +120,23 @@ class BadgeViewController: ModelScrollViewController { print("\(Self.self) updateView(viewModel)") badge.set(with: viewModel) } - - //Picker - var surfacePicker = SurfacePicker() - var fillColorPicker = PickerBase.init(items: BadgeFillColor.allCases) - var numberOfLinesPicker = PickerBase.init(items: NumberOfLines.allCases) - - var pickerType: PickerType = .surface { - didSet { - func update(object: UIPickerViewDelegate & UIPickerViewDataSource){ - picker.delegate = object - picker.dataSource = object - } - - switch pickerType{ - case .surface: - update(object: surfacePicker) - case .fillColor: - update(object: fillColorPicker) - case .numberOfLines: - update(object: numberOfLinesPicker) - } - picker.reloadAllComponents() - picker.selectRow(0, inComponent: 0, animated: false) - picker.isHidden = false - } - } func setupPicker(){ - surfacePicker.onPickerDidSelect = { [weak self] item in + + surfacePickerSelectorView.onPickerDidSelect = { [weak self] item in self?.badge.surface = item self?.contentTopView.backgroundColor = item.color self?.surfacePickerSelectorView.text = item.rawValue } - fillColorPicker.onPickerDidSelect = { [weak self] item in + fillColorPickerSelectorView.onPickerDidSelect = { [weak self] item in self?.badge.fillColor = item self?.fillColorPickerSelectorView.text = item.rawValue } - numberOfLinesPicker.onPickerDidSelect = { [weak self] item in + numberOfLinesPickerSelectorView.onPickerDidSelect = { [weak self] item in self?.badge.numberOfLines = item.intValue self?.numberOfLinesPickerSelectorView.text = item.rawValue } } } - diff --git a/VDSSample/ViewControllers/ButtonViewController.swift b/VDSSample/ViewControllers/ButtonViewController.swift index 08e7ad9..6cef054 100644 --- a/VDSSample/ViewControllers/ButtonViewController.swift +++ b/VDSSample/ViewControllers/ButtonViewController.swift @@ -11,13 +11,22 @@ import VDS import VDSColorTokens class ButtonViewController: ModelScrollViewController { - - enum PickerType { - case surface, use, buttonSize - } - var surfacePickerSelectorView = PickerSelectorView(title: "") - var usePickerSelectorView = PickerSelectorView(title: "") - var buttonSizePickerSelectorView = PickerSelectorView(title: "") + + lazy var surfacePickerSelectorView = { + SurfacePickerSelectorView(picker: self.picker) + }() + + lazy var usePickerSelectorView = { + PickerSelectorView(title: "", + picker: self.picker, + items: [.primary, .secondary]) + }() + + lazy var buttonSizePickerSelectorView = { + PickerSelectorView(title: "", + picker: self.picker, + items: ButtonSize.allCases) + }() var disabledSwitch = UISwitch() var textField = TextField() @@ -55,18 +64,6 @@ class ButtonViewController: ModelScrollViewController { self?.button.disabled = sender.isOn }.store(in: &subscribers) - surfacePickerSelectorView.button - .publisher(for: .touchUpInside) - .sink { [weak self] _ in - self?.pickerType = .surface - }.store(in: &subscribers) - - usePickerSelectorView.button - .publisher(for: .touchUpInside) - .sink { [weak self] _ in - self?.pickerType = .use - }.store(in: &subscribers) - textField .textPublisher .sink { [weak self] text in @@ -80,12 +77,6 @@ class ButtonViewController: ModelScrollViewController { self?.button.width = CGFloat(truncating: n) } }.store(in: &subscribers) - - buttonSizePickerSelectorView.button - .publisher(for: .touchUpInside) - .sink { [weak self] _ in - self?.pickerType = .buttonSize - }.store(in: &subscribers) } @@ -120,46 +111,21 @@ class ButtonViewController: ModelScrollViewController { button.set(with: viewModel) } - //Picker - var surfacePicker = SurfacePicker() - var usePicker = UsePicker() - var buttonSizePicker = PickerBase.init(items: ButtonSize.allCases) - - var pickerType: PickerType = .surface { - didSet { - func update(object: UIPickerViewDelegate & UIPickerViewDataSource){ - picker.delegate = object - picker.dataSource = object - } - - switch pickerType{ - case .surface: - update(object: surfacePicker) - case .use: - update(object: usePicker) - case .buttonSize: - update(object: buttonSizePicker) - } - picker.reloadAllComponents() - picker.selectRow(0, inComponent: 0, animated: false) - picker.isHidden = false - } - } - func setupPicker(){ - surfacePicker.onPickerDidSelect = { [weak self] item in + + surfacePickerSelectorView.onPickerDidSelect = { [weak self] item in self?.button.surface = item self?.contentTopView.backgroundColor = item.color self?.surfacePickerSelectorView.text = item.rawValue } - usePicker.onPickerDidSelect = { [weak self] item in + usePickerSelectorView.onPickerDidSelect = { [weak self] item in self?.button.use = item self?.button.backgroundColor = item.color self?.usePickerSelectorView.text = item.rawValue } - buttonSizePicker.onPickerDidSelect = { [weak self] item in + buttonSizePickerSelectorView.onPickerDidSelect = { [weak self] item in self?.button.size = item self?.buttonSizePickerSelectorView.text = item.rawValue } diff --git a/VDSSample/ViewControllers/CheckBoxGroupViewController.swift b/VDSSample/ViewControllers/CheckBoxGroupViewController.swift index 9518cf4..bbd2382 100644 --- a/VDSSample/ViewControllers/CheckBoxGroupViewController.swift +++ b/VDSSample/ViewControllers/CheckBoxGroupViewController.swift @@ -12,12 +12,11 @@ import VDSColorTokens import Combine class CheckboxGroupViewController: ModelScrollViewController { + + lazy var surfacePickerSelectorView = { + SurfacePickerSelectorView(picker: self.picker) + }() - enum PickerType { - case surface - } - - var surfacePickerSelectorView = PickerSelectorView(title: "light") var disabledSwitch = UISwitch() var labelTextField = TextField() var childTextField = TextField() @@ -65,12 +64,6 @@ class CheckboxGroupViewController: ModelScrollViewController { - - enum PickerType { - case surface - } - var surfacePickerSelectorView = PickerSelectorView(title: "light") + lazy var surfacePickerSelectorView = { + SurfacePickerSelectorView(picker: self.picker) + }() + var disabledSwitch = UISwitch() var labelTextField = TextField() var childTextField = TextField() @@ -78,13 +77,6 @@ class CheckboxViewController: ModelScrollViewController { .sink { [weak self] text in self?.checkbox.errorText = text }.store(in: &subscribers) - - - surfacePickerSelectorView.button - .publisher(for: .touchUpInside) - .sink { [weak self] _ in - self?.pickerType = .surface - }.store(in: &subscribers) } func setupModel() { @@ -124,26 +116,8 @@ class CheckboxViewController: ModelScrollViewController { } //Picker - var surfacePicker = SurfacePicker() - var pickerType: PickerType = .surface { - didSet { - func update(object: UIPickerViewDelegate & UIPickerViewDataSource){ - picker.delegate = object - picker.dataSource = object - } - - switch pickerType{ - case .surface: - update(object: surfacePicker) - } - picker.reloadAllComponents() - picker.selectRow(0, inComponent: 0, animated: false) - picker.isHidden = false - } - } - func setupPicker(){ - surfacePicker.onPickerDidSelect = { [weak self] item in + surfacePickerSelectorView.onPickerDidSelect = { [weak self] item in self?.checkbox.surface = item self?.contentTopView.backgroundColor = item.color self?.surfacePickerSelectorView.text = item.rawValue diff --git a/VDSSample/ViewControllers/LabelViewController.swift b/VDSSample/ViewControllers/LabelViewController.swift index 0dab835..b5b3499 100644 --- a/VDSSample/ViewControllers/LabelViewController.swift +++ b/VDSSample/ViewControllers/LabelViewController.swift @@ -12,12 +12,20 @@ import VDSColorTokens class LabelViewController: ModelScrollViewController { - enum PickerType { - case surface, textSize, fontCategory - } - var surfacePickerSelectorView = PickerSelectorView(title: "") - var textSizePickerSelectorView = PickerSelectorView(title: "") - var fontCategoryPickerSelectorView = PickerSelectorView(title: "") + lazy var surfacePickerSelectorView = { + SurfacePickerSelectorView(picker: self.picker) + }() + + lazy var textSizePickerSelectorView = { + TextSizePickerSelectorView(title: "", + picker: self.picker) + }() + + lazy var fontCategoryPickerSelectorView = { + FontCategoryPickerSelectorView(title: "", + picker: self.picker) + }() + var boldSwitch = UISwitch() var disabledSwitch = UISwitch() var textField = TextField() @@ -55,24 +63,6 @@ class LabelViewController: ModelScrollViewController { self?.updateLabelStyle() }.store(in: &subscribers) - surfacePickerSelectorView.button - .publisher(for: .touchUpInside) - .sink { [weak self] _ in - self?.pickerType = .surface - }.store(in: &subscribers) - - fontCategoryPickerSelectorView.button - .publisher(for: .touchUpInside) - .sink { [weak self] _ in - self?.pickerType = .fontCategory - }.store(in: &subscribers) - - textSizePickerSelectorView.button - .publisher(for: .touchUpInside) - .sink { [weak self] _ in - self?.pickerType = .textSize - }.store(in: &subscribers) - textField .textPublisher .sink { [weak self] text in @@ -110,37 +100,12 @@ class LabelViewController: ModelScrollViewController { } //Picker - var surfacePicker = SurfacePicker() - var textSizePicker = TextSizePicker() - var fontCategoryPicker = FontCategoryPicker() - - var pickerType: PickerType = .surface { - didSet { - func update(object: UIPickerViewDelegate & UIPickerViewDataSource){ - picker.delegate = object - picker.dataSource = object - } - - switch pickerType{ - case .surface: - update(object: surfacePicker) - case .textSize: - update(object: textSizePicker) - case .fontCategory: - update(object: fontCategoryPicker) - } - picker.reloadAllComponents() - picker.selectRow(0, inComponent: 0, animated: false) - picker.isHidden = false - } - } - private var fontCategory: TypographicalStyle.FontCategory = .feature { didSet { fontCategoryPickerSelectorView.text = fontCategory.rawValue - textSizePicker.items = fontCategory.sizes - if textSizePicker.items.count > 0 { - textSize = textSizePicker.items[0] + textSizePickerSelectorView.items = fontCategory.sizes + if textSizePickerSelectorView.items.count > 0 { + textSize = textSizePickerSelectorView.items[0] } else { textSize = nil } @@ -161,19 +126,19 @@ class LabelViewController: ModelScrollViewController { label.typograpicalStyle = style } } - + func setupPicker(){ - surfacePicker.onPickerDidSelect = { [weak self] item in + surfacePickerSelectorView.onPickerDidSelect = { [weak self] item in self?.label.surface = item self?.contentTopView.backgroundColor = item.color self?.surfacePickerSelectorView.text = item.rawValue } - textSizePicker.onPickerDidSelect = { [weak self] item in + textSizePickerSelectorView.onPickerDidSelect = { [weak self] item in self?.textSize = item } - fontCategoryPicker.onPickerDidSelect = { [weak self] item in + fontCategoryPickerSelectorView.onPickerDidSelect = { [weak self] item in self?.fontCategory = item } } diff --git a/VDSSample/ViewControllers/RadioBoxGroupViewController.swift b/VDSSample/ViewControllers/RadioBoxGroupViewController.swift index d2b54b5..e5b6960 100644 --- a/VDSSample/ViewControllers/RadioBoxGroupViewController.swift +++ b/VDSSample/ViewControllers/RadioBoxGroupViewController.swift @@ -13,13 +13,12 @@ import Combine class RadioBoxGroupViewController: ModelScrollViewController { - enum PickerType { - case surface - } - + lazy var surfacePickerSelectorView = { + SurfacePickerSelectorView(picker: self.picker) + }() + var disabledSwitch = UISwitch() var strikeThroughSwitch = UISwitch() - var surfacePickerSelectorView = PickerSelectorView(title: "light") var textField = TextField() var subTextField = TextField() var subTextRightField = TextField() @@ -73,12 +72,6 @@ class RadioBoxGroupViewController: ModelScrollViewController { - enum PickerType { - case surface - } - var surfacePickerSelectorView = PickerSelectorView(title: "light") + lazy var surfacePickerSelectorView = { + SurfacePickerSelectorView(picker: self.picker) + }() + var disabledSwitch = UISwitch() var labelTextField = TextField() var childTextField = TextField() @@ -39,19 +39,19 @@ class RadioButtonViewController: ModelScrollViewController { - enum PickerType { - case surface - } - + lazy var surfacePickerSelectorView = { + SurfacePickerSelectorView(picker: self.picker) + }() + var disabledSwitch = UISwitch() var strikeThroughSwitch = UISwitch() - var surfacePickerSelectorView = PickerSelectorView(title: "light") - var radioSwatchGroup = RadioSwatchGroup() override func viewDidLoad() { @@ -58,12 +56,6 @@ class RadioSwatchGroupViewController: ModelScrollViewController { - enum PickerType { - case surface, textSize, textPosition - } + lazy var surfacePickerSelectorView = { + SurfacePickerSelectorView(picker: self.picker) + }() + + lazy var textSizePickerSelectorView = { + TextSizePickerSelectorView(title: "Small", + picker: self.picker) + }() + + lazy var textPositionPickerSelectorView = { + TextPositionPickerSelectorView(picker: self.picker) + }() - var surfacePickerSelectorView = PickerSelectorView(title: "light") var disabledSwitch = UISwitch() var showTextSwitch = UISwitch() @@ -31,8 +39,6 @@ class ToggleViewController: ModelScrollViewController { }() var boldSwitch = UISwitch() - var textSizePickerSelectorView = PickerSelectorView(title: "Large") - var textPositionPickerSelectorView = PickerSelectorView(title: "left") var onTextField = TextField() var offTextField = TextField() @@ -72,24 +78,6 @@ class ToggleViewController: ModelScrollViewController { self?.textFormStackView.isHidden = !sender.isOn }.store(in: &subscribers) - surfacePickerSelectorView.button - .publisher(for: .touchUpInside) - .sink { [weak self] _ in - self?.pickerType = .surface - }.store(in: &subscribers) - - textSizePickerSelectorView.button - .publisher(for: .touchUpInside) - .sink { [weak self] _ in - self?.pickerType = .textSize - }.store(in: &subscribers) - - textPositionPickerSelectorView.button - .publisher(for: .touchUpInside) - .sink { [weak self] _ in - self?.pickerType = .textPosition - }.store(in: &subscribers) - disabledSwitch .publisher(for: .valueChanged) .sink { [weak self] sender in @@ -123,47 +111,24 @@ class ToggleViewController: ModelScrollViewController { } //Picker - var surfacePicker = SurfacePicker() - var textSizePicker = TextSizePicker() - var textPositionPicker = TextPositionPicker() - - var pickerType: PickerType = .surface { - didSet { - func update(object: UIPickerViewDelegate & UIPickerViewDataSource){ - picker.delegate = object - picker.dataSource = object - } - - switch pickerType{ - case .surface: - update(object: surfacePicker) - case .textSize: - update(object: textSizePicker) - case .textPosition: - update(object: textPositionPicker) - } - picker.reloadAllComponents() - picker.selectRow(0, inComponent: 0, animated: false) - picker.isHidden = false - } - } - + func setupPicker(){ - - surfacePicker.onPickerDidSelect = { [weak self] item in + + surfacePickerSelectorView.onPickerDidSelect = { [weak self] item in self?.toggle.surface = item self?.contentTopView.backgroundColor = item.color self?.surfacePickerSelectorView.text = item.rawValue } - textSizePicker.onPickerDidSelect = { [weak self] item in + textSizePickerSelectorView.onPickerDidSelect = { [weak self] item in self?.toggle.fontSize = item self?.textSizePickerSelectorView.text = item.rawValue } - textPositionPicker.onPickerDidSelect = { [weak self] item in + textPositionPickerSelectorView.onPickerDidSelect = { [weak self] item in self?.toggle.textPosition = item self?.textPositionPickerSelectorView.text = item.rawValue } + } }