diff --git a/VDSSample.xcodeproj/project.pbxproj b/VDSSample.xcodeproj/project.pbxproj index f8c2565..4ec33f9 100644 --- a/VDSSample.xcodeproj/project.pbxproj +++ b/VDSSample.xcodeproj/project.pbxproj @@ -41,6 +41,7 @@ EA3C3BB528996775000CA526 /* StoryboardInitable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3C3BB128996775000CA526 /* StoryboardInitable.swift */; }; EA3C3BB628996775000CA526 /* MenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3C3BB228996775000CA526 /* MenuViewController.swift */; }; EA3C3BB728996775000CA526 /* ToggleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3C3BB328996775000CA526 /* ToggleViewController.swift */; }; + EA4DB30428DCD25B00103EE3 /* BadgeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4DB30328DCD25B00103EE3 /* BadgeViewController.swift */; }; EA84F76228BE4AE500D67ABC /* RadioSwatchGroupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F76128BE4AE500D67ABC /* RadioSwatchGroupViewController.swift */; }; EA89201928B56DF5006B9984 /* RadioBoxGroupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89201828B56DF5006B9984 /* RadioBoxGroupViewController.swift */; }; EA89204628B66CE2006B9984 /* ScrollViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89203F28B66CE2006B9984 /* ScrollViewController.swift */; }; @@ -103,6 +104,7 @@ EA3C3BBA289968A0000CA526 /* VDSTypographyTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSTypographyTokens.xcframework; path = ../SharedFrameworks/VDSTypographyTokens.xcframework; sourceTree = ""; }; EA3C3BBB289968A0000CA526 /* VDSFormControlsTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSFormControlsTokens.xcframework; path = ../SharedFrameworks/VDSFormControlsTokens.xcframework; sourceTree = ""; }; EA3C3BC3289968B1000CA526 /* VDS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = VDS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + EA4DB30328DCD25B00103EE3 /* BadgeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeViewController.swift; sourceTree = ""; }; EA84F76128BE4AE500D67ABC /* RadioSwatchGroupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioSwatchGroupViewController.swift; sourceTree = ""; }; EA89201828B56DF5006B9984 /* RadioBoxGroupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBoxGroupViewController.swift; sourceTree = ""; }; EA89203F28B66CE2006B9984 /* ScrollViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScrollViewController.swift; sourceTree = ""; }; @@ -246,6 +248,7 @@ EA89203E28B66CE2006B9984 /* ScrollViewController */, EA3C3BB228996775000CA526 /* MenuViewController.swift */, EAB1D2C828AAAA1D00DAE764 /* ModelScrollViewController.swift */, + EA4DB30328DCD25B00103EE3 /* BadgeViewController.swift */, EA89204D28B67332006B9984 /* CheckBoxGroupViewController.swift */, EAF7F09B2899B92400B287F5 /* CheckboxViewController.swift */, EAB1D2D328AC409F00DAE764 /* LabelViewController.swift */, @@ -412,6 +415,7 @@ EA3C3BB428996775000CA526 /* PickerBase.swift in Sources */, EAB1D2C928AAAA1D00DAE764 /* ModelScrollViewController.swift in Sources */, EA89204728B66CE2006B9984 /* KeyboardFrameChangeListener.swift in Sources */, + EA4DB30428DCD25B00103EE3 /* BadgeViewController.swift in Sources */, EA89204828B66CE2006B9984 /* ScrollViewKeyboardAvoiding.swift in Sources */, EAF7F09C2899B92400B287F5 /* CheckboxViewController.swift in Sources */, EA89204E28B67332006B9984 /* CheckBoxGroupViewController.swift in Sources */, diff --git a/VDSSample/ViewControllers/BadgeViewController.swift b/VDSSample/ViewControllers/BadgeViewController.swift new file mode 100644 index 0000000..a0d39cf --- /dev/null +++ b/VDSSample/ViewControllers/BadgeViewController.swift @@ -0,0 +1,178 @@ +// +// BadgeViewController.swift +// VDSSample +// +// Created by Matt Bruce on 9/22/22. +// + +import Foundation +import UIKit +import VDS +import VDSColorTokens +import Combine + +class BadgeViewController: ModelScrollViewController { + + enum PickerType { + case surface, fillColor, numberOfLines + } + + enum NumberOfLines: String, CaseIterable { + case unlimited + case one + case two + case three + case four + + var intValue: Int { + switch self { + + case .unlimited: + return 0 + case .one: + return 1 + case .two: + return 2 + case .three: + return 3 + case .four: + return 4 + } + } + } + + var fillColorPickerSelectorView = PickerSelectorView(title: "red") + var numberOfLinesPickerSelectorView = PickerSelectorView(title: "one") + var surfacePickerSelectorView = PickerSelectorView(title: "light") + var textField = TextField() + var maxWidthTextField = TextField() + var badge = Badge() + + override func viewDidLoad() { + super.viewDidLoad() + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(badge) + badge.topAnchor.constraint(equalTo: view.topAnchor).isActive = true + badge.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true + badge.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true + addContentTopView(view: view) + + setupForm() + setupPicker() + setupModel() + } + + func setupForm(){ + addFormRow(label: "Fill Color", view: fillColorPickerSelectorView) + addFormRow(label: "Surface", view: surfacePickerSelectorView) + addFormRow(label: "Text", view: textField) + addFormRow(label: "Width", view: maxWidthTextField) + addFormRow(label: "Number of Lines", view: numberOfLinesPickerSelectorView) + + textField + .textPublisher + .sink { [weak self] text in + self?.badge.text = text + }.store(in: &subscribers) + + maxWidthTextField + .textPublisher + .sink { [weak self] text in + var float: CGFloat? + if let n = NumberFormatter().number(from: text) { + float = CGFloat(truncating: n) + } + 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() { + var defaultModel = DefaultBadgeModel() + defaultModel.fillColor = .red + defaultModel.text = "Terms and conditions" + defaultModel.numberOfLines = 1 + + set(with: defaultModel) + + badge + .handlerPublisher() + .sink { [weak self] viewModel in + self?.model = viewModel + }.store(in: &subscribers) + + + //setup UI + surfacePickerSelectorView.text = model.surface.rawValue + textField.text = model.text + } + + override func updateView(viewModel: DefaultBadgeModel) { + 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 + self?.badge.surface = item + self?.contentTopView.backgroundColor = item.color + self?.surfacePickerSelectorView.text = item.rawValue + } + + fillColorPicker.onPickerDidSelect = { [weak self] item in + self?.badge.fillColor = item + self?.fillColorPickerSelectorView.text = item.rawValue + } + + numberOfLinesPicker.onPickerDidSelect = { [weak self] item in + self?.badge.numberOfLines = item.intValue + self?.numberOfLinesPickerSelectorView.text = item.rawValue + } + } +} + diff --git a/VDSSample/ViewControllers/MenuViewController.swift b/VDSSample/ViewControllers/MenuViewController.swift index 1d705a9..7c3bfa1 100644 --- a/VDSSample/ViewControllers/MenuViewController.swift +++ b/VDSSample/ViewControllers/MenuViewController.swift @@ -19,6 +19,7 @@ protocol Initable { class MenuViewController: UITableViewController { let items: [MenuComponent] = [ + MenuComponent(title: "Badge", viewController: BadgeViewController.self), MenuComponent(title: "Checkbox", viewController: CheckboxViewController.self), MenuComponent(title: "CheckboxGroup", viewController: CheckboxGroupViewController.self), MenuComponent(title: "Label", viewController: LabelViewController.self), diff --git a/VDSSample/ViewControllers/ModelScrollViewController.swift b/VDSSample/ViewControllers/ModelScrollViewController.swift index 7b4b367..a1cd1f4 100644 --- a/VDSSample/ViewControllers/ModelScrollViewController.swift +++ b/VDSSample/ViewControllers/ModelScrollViewController.swift @@ -129,7 +129,7 @@ public class ModelScrollViewController: UIViewController, contentBottomView.topAnchor.constraint(equalTo: contentTopView.bottomAnchor, constant: edgeSpacing).isActive = true contentBottomView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: edgeSpacing).isActive = true contentBottomView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -edgeSpacing).isActive = true - contentBottomView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -edgeSpacing).isActive = true + contentBottomView.bottomAnchor.constraint(lessThanOrEqualTo: contentView.bottomAnchor, constant: -edgeSpacing).isActive = true formStackView.topAnchor.constraint(equalTo: contentBottomView.topAnchor, constant: edgeSpacing).isActive = true formStackView.leadingAnchor.constraint(equalTo: contentBottomView.leadingAnchor, constant: edgeSpacing).isActive = true @@ -159,9 +159,10 @@ public class ModelScrollViewController: UIViewController, open func addContentTopView(view: UIView) { contentTopView.addSubview(view) view.leadingAnchor.constraint(equalTo: contentTopView.leadingAnchor, constant: edgeSpacing).isActive = true - view.trailingAnchor.constraint(lessThanOrEqualTo: contentTopView.trailingAnchor, constant: -edgeSpacing).isActive = true view.topAnchor.constraint(equalTo: contentTopView.topAnchor, constant: topBottomSpacing).isActive = true - view.bottomAnchor.constraint(equalTo: contentTopView.bottomAnchor, constant: -topBottomSpacing).isActive = true + + view.trailingAnchor.constraint(lessThanOrEqualTo: contentTopView.trailingAnchor, constant: -edgeSpacing).isActive = true + view.bottomAnchor.constraint(lessThanOrEqualTo: contentTopView.bottomAnchor, constant: -topBottomSpacing).isActive = true } open func addFormRow(label: String, view: UIView, stackView: UIStackView? = nil) {