diff --git a/VDS/Components/RadioSwatch/RadioSwatchGroup.swift b/VDS/Components/RadioSwatch/RadioSwatchGroup.swift index 9a97fab3..a5eabdd5 100644 --- a/VDS/Components/RadioSwatch/RadioSwatchGroup.swift +++ b/VDS/Components/RadioSwatch/RadioSwatchGroup.swift @@ -8,8 +8,9 @@ import Foundation import UIKit -public class RadioSwatchGroup: Control, Changable { - public typealias ModelHandlerType = RadioSwatch +public class RadioSwatchGroup: RadioSwatchGroupBase {} + +public class RadioSwatchGroupBase: Control, Changable, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate where GroupModelType.SelectorModelType == ModelHandlerType.ModelType { //-------------------------------------------------- // MARK: - Public Properties @@ -26,23 +27,12 @@ public class RadioSwatchGroup: Control, Changable //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- - private var contentView: UIView = { - return UIView().with { - $0.translatesAutoresizingMaskIntoConstraints = false - $0.backgroundColor = .clear - - } - }() - private var label = Label() private let cellSize: CGFloat = 48.0 private let lineSpacing: CGFloat = 12.0 private let itemSpacing: CGFloat = 16.0 - public var collectionViewHeight: NSLayoutConstraint? - public var collectionViewWidth: NSLayoutConstraint? - private lazy var collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout().with { $0.minimumLineSpacing = lineSpacing @@ -76,29 +66,20 @@ public class RadioSwatchGroup: Control, Changable super.setup() isAccessibilityElement = true accessibilityTraits = .button - addSubview(contentView) - contentView.addSubview(label) - contentView.addSubview(collectionView) + addSubview(label) + addSubview(collectionView) NSLayoutConstraint.activate([ - contentView.topAnchor.constraint(equalTo: topAnchor), - contentView.leadingAnchor.constraint(equalTo: leadingAnchor), - contentView.trailingAnchor.constraint(equalTo: trailingAnchor), - contentView.bottomAnchor.constraint(equalTo: bottomAnchor), - label.topAnchor.constraint(equalTo: contentView.topAnchor), - label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), - label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), + label.topAnchor.constraint(equalTo: topAnchor), + label.leadingAnchor.constraint(equalTo: leadingAnchor), + label.trailingAnchor.constraint(equalTo: trailingAnchor), collectionView.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 24), - collectionView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), - collectionView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), - collectionView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor) + collectionView.leadingAnchor.constraint(equalTo: leadingAnchor), + collectionView.trailingAnchor.constraint(equalTo: trailingAnchor), + collectionView.bottomAnchor.constraint(equalTo: bottomAnchor), + collectionView.heightAnchor.constraint(greaterThanOrEqualToConstant: cellSize), + collectionView.widthAnchor.constraint(greaterThanOrEqualToConstant: cellSize * 10) ]) - collectionViewHeight = collectionView.heightAnchor.constraint(greaterThanOrEqualToConstant: cellSize) - collectionViewHeight?.isActive = true - - collectionViewWidth = collectionView.widthAnchor.constraint(greaterThanOrEqualToConstant: cellSize * 10) - collectionViewWidth?.isActive = true - } open override func shouldUpdateView(viewModel: ModelType) -> Bool { @@ -116,38 +97,6 @@ public class RadioSwatchGroup: Control, Changable collectionView.reloadData() setNeedsLayout() } - - //-------------------------------------------------- - // MARK: - Lifecycle - //-------------------------------------------------- -// open override func layoutSubviews() { -// super.layoutSubviews() -// // Accounts for any collection size changes -// //setHeight() -//// DispatchQueue.main.async { [weak self] in -//// self?.collectionView.collectionViewLayout.invalidateLayout() -//// } -// } - - open func setHeight() { - let bounds = collectionView.bounds - if bounds.width <= 0 { - return - } - if model.selectors.count > 0 { - // Calculate the height - let swatchesInRow = floor(CGFloat(bounds.width/(cellSize + itemSpacing))) - let numberOfRows = ceil(CGFloat(model.selectors.count)/swatchesInRow) - let height = (numberOfRows * cellSize) + (itemSpacing * (numberOfRows-1)) - - if let oldHeight = collectionViewHeight?.constant, - height != oldHeight { - } - collectionViewHeight?.constant = CGFloat(height) - } else { - collectionViewHeight?.constant = 0 - } - } //Refactor into new CollectionView Selector protocol public func updateSelectors(){ @@ -167,22 +116,24 @@ public class RadioSwatchGroup: Control, Changable model.selectors[index] = viewModel } } -} - -extension RadioSwatchGroup: UICollectionViewDelegateFlowLayout { + + //-------------------------------------------------- + // MARK: - UICollectionViewDelegateFlowLayout + //-------------------------------------------------- open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: cellSize, height: cellSize) } -} - -extension RadioSwatchGroup: UICollectionViewDelegate { + + //-------------------------------------------------- + // MARK: - UICollectionViewDelegate + //-------------------------------------------------- open func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { return !model.selectors[indexPath.row].disabled } open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { guard let cell = collectionView.cellForItem(at: indexPath) as? CollectionViewCell else { return } - + //reset the old model if let selectedModel { let oldSelectedModel = selectedModel.copyWith { @@ -199,19 +150,21 @@ extension RadioSwatchGroup: UICollectionViewDelegate { label.text = newSelectedModel.text replace(viewModel: newSelectedModel) selectedModel = newSelectedModel - + } open func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { guard let cell = collectionView.cellForItem(at: indexPath) as? CollectionViewCell else { return } cell.isSelected = false } -} - -extension RadioSwatchGroup: UICollectionViewDataSource { + + //-------------------------------------------------- + // MARK: - UICollectionViewDataSource + //-------------------------------------------------- public func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } + public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return model.selectors.count }