188 lines
6.7 KiB
Swift
188 lines
6.7 KiB
Swift
//
|
|
// TileletGroup.swift
|
|
// VDS
|
|
//
|
|
// Created by Matt Bruce on 10/8/24.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
import VDSCoreTokens
|
|
import Combine
|
|
|
|
open class TileletGroup: View {
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Private Properties
|
|
//--------------------------------------------------
|
|
|
|
/// CollectionView to show the rows and columns
|
|
private lazy var matrixView = SelfSizingCollectionView(frame: .zero, collectionViewLayout: flowLayout).with {
|
|
$0.register(TileletGroupCellItem.self, forCellWithReuseIdentifier: TileletGroupCellItem.Identifier)
|
|
$0.dataSource = self
|
|
$0.delegate = self
|
|
$0.translatesAutoresizingMaskIntoConstraints = false
|
|
$0.allowsSelection = false
|
|
$0.showsVerticalScrollIndicator = false
|
|
$0.showsHorizontalScrollIndicator = false
|
|
$0.isAccessibilityElement = true
|
|
$0.backgroundColor = .clear
|
|
}
|
|
|
|
/// Custom flow layout to manage the height of the cells
|
|
private lazy var flowLayout = TileletGroupFlowLayout().with {
|
|
$0.delegate = self
|
|
$0.scrollDirection = .horizontal
|
|
}
|
|
|
|
/// Parameter to show the all table rows
|
|
private var rows: [[Tilelet]] = [] { didSet { setNeedsUpdate() } }
|
|
//--------------------------------------------------
|
|
// MARK: - Enums
|
|
//--------------------------------------------------
|
|
|
|
/// Enums used to define the padding for the cell edge spacing.
|
|
public enum Padding: String, CaseIterable {
|
|
case standard, compact
|
|
|
|
private func value() -> CGFloat {
|
|
switch self {
|
|
case .standard:
|
|
return UIDevice.isIPad ? 40.0 : VDSLayout.space3X
|
|
case .compact:
|
|
return UIDevice.isIPad ? VDSLayout.space6X : VDSLayout.space3X
|
|
}
|
|
}
|
|
|
|
func horizontalValue() -> CGFloat { value() }
|
|
|
|
func verticalValue() -> CGFloat { value() }
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Public Properties
|
|
//--------------------------------------------------
|
|
/// Parameter to set the padding for the cell
|
|
open var padding: Padding = .standard { didSet { setNeedsUpdate() } }
|
|
|
|
/// An object containing number of Button components per row for iPhones
|
|
open var rowQuantityPhone: Int = 2 { didSet { updateRows() } }
|
|
|
|
/// An object containing number of Button components per row for iPads
|
|
open var rowQuantityTablet: Int = 4 { didSet { updateRows() } }
|
|
|
|
/// An object containing number of Button components per row
|
|
open var rowQuantity: Int { UIDevice.isIPad ? rowQuantityTablet : rowQuantityPhone }
|
|
|
|
open var tilelets: [Tilelet] = [] { didSet { updateRows() } }
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Overrides
|
|
//--------------------------------------------------
|
|
|
|
///Called upon initializing the table view
|
|
open override func setup() {
|
|
super.setup()
|
|
addSubview(matrixView)
|
|
matrixView.pinToSuperView()
|
|
}
|
|
|
|
/// Will update the table view, when called becasue of any changes in component parameters
|
|
open override func updateView() {
|
|
super.updateView()
|
|
flowLayout.verticalPadding = padding.verticalValue()
|
|
flowLayout.horizontalPadding = padding.horizontalValue()
|
|
matrixView.reloadData()
|
|
matrixView.collectionViewLayout.invalidateLayout()
|
|
}
|
|
|
|
open override func setDefaults() {
|
|
super.setDefaults()
|
|
padding = .standard
|
|
rows = [[]]
|
|
}
|
|
|
|
func updateRows() {
|
|
var tempRows: [[Tilelet]] = []
|
|
for i in stride(from: 0, to: tilelets.count, by: rowQuantity) {
|
|
let endIndex = min(i + rowQuantity, tilelets.count)
|
|
let row = Array(tilelets[i..<endIndex])
|
|
tempRows.append(row)
|
|
}
|
|
rows = tempRows
|
|
}
|
|
}
|
|
|
|
extension TileletGroup: UICollectionViewDelegate, UICollectionViewDataSource, TiletGroupCollectionViewLayoutDataDelegate {
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - UICollectionViewDelegate & UICollectionViewDataSource
|
|
//--------------------------------------------------
|
|
|
|
public func numberOfSections(in collectionView: UICollectionView) -> Int {
|
|
return rows.count
|
|
}
|
|
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
|
return rows[section].count
|
|
}
|
|
|
|
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
|
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TileletGroupCellItem.Identifier, for: indexPath) as? TileletGroupCellItem else { return UICollectionViewCell() }
|
|
let currentItem = rows[indexPath.section][indexPath.row]
|
|
cell.updateCell(component: currentItem)
|
|
// let rowColors: (UIColor,UIColor) = indexPath.section % 2 == 0 ? (.green, .yellow) : (.blue, .brown)
|
|
// cell.backgroundColor = indexPath.row % 2 == 0 ? rowColors.0 : rowColors.1
|
|
return cell
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - TableCollectionViewLayoutDataDelegate
|
|
//--------------------------------------------------
|
|
|
|
internal func collectionView(_ collectionView: UICollectionView, dataForItemAt indexPath: IndexPath) -> Tilelet {
|
|
return rows[indexPath.section][indexPath.row]
|
|
}
|
|
}
|
|
|
|
final class TileletGroupCellItem: UICollectionViewCell {
|
|
|
|
/// Identifier for TableCellItem
|
|
static let Identifier: String = String(describing: TileletGroupCellItem.self)
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Private Properties
|
|
//--------------------------------------------------
|
|
|
|
/// Main view which holds the content of the cell
|
|
private let containerView = View()
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Initializers
|
|
//--------------------------------------------------
|
|
override init(frame: CGRect) {
|
|
super.init(frame: frame)
|
|
setupCell()
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
super.init(coder: coder)
|
|
setupCell()
|
|
}
|
|
|
|
private func setupCell() {
|
|
contentView.backgroundColor = .clear
|
|
addSubview(containerView)
|
|
containerView.pinToSuperView()
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Public Methods
|
|
//--------------------------------------------------
|
|
|
|
public func updateCell(component: Tilelet) {
|
|
containerView.subviews.forEach({ $0.removeFromSuperview() })
|
|
containerView.addSubview(component)
|
|
component.pinToSuperView()
|
|
}
|
|
}
|