149 lines
5.8 KiB
Swift
149 lines
5.8 KiB
Swift
//
|
|
// Table.swift
|
|
// VDS
|
|
//
|
|
// Created by Nadigadda, Sumanth on 24/04/24.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
import VDSTokens
|
|
|
|
@objc(VDSTable)
|
|
open class Table: View {
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Private Properties
|
|
//--------------------------------------------------
|
|
|
|
private lazy var matrixView = SelfSizingCollectionView(frame: .zero, collectionViewLayout: flowLayout).with {
|
|
$0.register(TableCellItem.self, forCellWithReuseIdentifier: TableCellItem.Identifier)
|
|
$0.dataSource = self
|
|
$0.delegate = self
|
|
$0.translatesAutoresizingMaskIntoConstraints = false
|
|
$0.allowsSelection = false
|
|
$0.isScrollEnabled = false
|
|
$0.showsVerticalScrollIndicator = false
|
|
$0.showsHorizontalScrollIndicator = false
|
|
$0.isAccessibilityElement = true
|
|
$0.backgroundColor = .clear
|
|
}
|
|
|
|
private let flowLayout = MatrixFlowLayout().with {
|
|
$0.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
|
|
$0.minimumLineSpacing = 0
|
|
$0.minimumInteritemSpacing = 0
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Enums
|
|
//--------------------------------------------------
|
|
|
|
public enum Padding: String, CaseIterable {
|
|
case standard, compact
|
|
|
|
func horizontalValue() -> CGFloat {
|
|
switch self {
|
|
case .standard:
|
|
return UIDevice.isIPad ? VDSLayout.space8X : VDSLayout.space6X
|
|
case .compact:
|
|
return UIDevice.isIPad ? VDSLayout.space8X : VDSLayout.space6X
|
|
}
|
|
}
|
|
|
|
func verticalValue() -> CGFloat {
|
|
switch self {
|
|
case .standard:
|
|
return UIDevice.isIPad ? VDSLayout.space8X : VDSLayout.space6X
|
|
case .compact:
|
|
return UIDevice.isIPad ? VDSLayout.space4X : VDSLayout.space3X
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Public Properties
|
|
//--------------------------------------------------
|
|
|
|
open var striped: Bool = false { didSet { setNeedsUpdate() } }
|
|
|
|
open var padding: Padding = .standard { didSet { setNeedsUpdate() } }
|
|
|
|
open var headerBottomLine: Bool = false { didSet { setNeedsUpdate() } }
|
|
|
|
open var rowBottomLine: Bool = false { didSet { setNeedsUpdate() } }
|
|
|
|
open var headerBottomLineType: Line.Style = .primary { didSet { setNeedsUpdate() } }
|
|
|
|
open var rowBottomLineType: Line.Style = .secondary { didSet { setNeedsUpdate() } }
|
|
|
|
open var tableData: [[TableCellModel]]? { didSet { setNeedsUpdate() } }
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Overrides
|
|
//--------------------------------------------------
|
|
|
|
open override func initialSetup() {
|
|
super.initialSetup()
|
|
addSubview(matrixView)
|
|
matrixView.pinToSuperView()
|
|
}
|
|
|
|
open override func updateView() {
|
|
super.updateView()
|
|
matrixView.reloadData()
|
|
}
|
|
}
|
|
|
|
extension Table : UICollectionViewDelegate, UICollectionViewDataSource {
|
|
|
|
public func numberOfSections(in collectionView: UICollectionView) -> Int {
|
|
return tableData?.count ?? 0
|
|
}
|
|
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
|
return tableData?[section].count ?? 0
|
|
}
|
|
|
|
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
|
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TableCellItem.Identifier, for: indexPath) as? TableCellItem,
|
|
let currentItem = tableData?[indexPath.section][indexPath.row]
|
|
else { return UICollectionViewCell() }
|
|
let shouldStrip = striped ? (indexPath.section % 2 != 0) : false
|
|
let style = indexPath.section == 0 ? headerBottomLineType : rowBottomLineType
|
|
let hideSeparator = indexPath.section == 0 ? headerBottomLine : rowBottomLine
|
|
cell.updateCell(content: currentItem, surface: surface, separatorStyle: style, isHeader: indexPath.section == 0, hideSeparator: hideSeparator, striped: shouldStrip, padding: padding)
|
|
return cell
|
|
}
|
|
}
|
|
|
|
extension Table: UICollectionViewDelegateFlowLayout {
|
|
|
|
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
|
|
guard let sectionCount = tableData?[indexPath.section].count else { return CGSize.zero }
|
|
let width = Int(collectionView.frame.width) / sectionCount
|
|
return CGSize(width: width, height: 100)
|
|
}
|
|
}
|
|
|
|
final class MatrixFlowLayout : UICollectionViewFlowLayout {
|
|
|
|
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
|
|
guard let layoutAttributesObjects = super.layoutAttributesForElements(in: rect) else { return nil }
|
|
layoutAttributesObjects.forEach({ layoutAttributes in
|
|
if layoutAttributes.representedElementCategory == .cell,
|
|
let newFrame = layoutAttributesForItem(at: layoutAttributes.indexPath)?.frame {
|
|
layoutAttributes.frame = newFrame
|
|
}
|
|
})
|
|
return layoutAttributesObjects
|
|
}
|
|
|
|
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
|
|
guard let collectionView = collectionView,
|
|
let layoutAttributes = super.layoutAttributesForItem(at: indexPath) else { return nil }
|
|
let itemsCount = CGFloat(collectionView.numberOfItems(inSection: indexPath.section))
|
|
layoutAttributes.frame.size.width = ceil(collectionView.safeAreaLayoutGuide.layoutFrame.width / itemsCount)
|
|
return layoutAttributes
|
|
}
|
|
}
|