vds_ios/VDS/Components/Pagination/Pagination.swift
2024-03-05 16:48:26 +05:30

150 lines
5.3 KiB
Swift

//
// Pagination.swift
// VDS
//
// Created by Bandaru, Krishna Kishore on 01/03/24.
//
import Foundation
import VDSColorTokens
import Combine
@objc(VDSPagination)
open class Pagination: View {
open var onPageDidSelect: ((Int) -> Void)?
public let previousButton: PaginationButton = .init(type: .previous)
public let nextButton: PaginationButton = .init(type: .next)
public var total: Int = 0 {
didSet {
previousButton.isHidden = true
nextButton.isHidden = total <= 1
_selectedPage = 0
setNeedsUpdate()
}
}
public var selectedPage: Int {
set {
if newValue >= total {
_selectedPage = total - 1
} else if newValue < 0 {
_selectedPage = 0
} else {
_selectedPage = max(newValue - 1, 0)
}
setNeedsUpdate()
updateSelection()
}
get {
_selectedPage
}
}
private var _selectedPage: Int = 0
private let pageItemCellSize: CGSize = .init(width: 20, height: 16)
private let spacingBetweenCell: CGFloat = VDSLayout.Spacing.space1X.value
private let containerView: View = View().with {
$0.translatesAutoresizingMaskIntoConstraints = false
}
private lazy var flowLayout: UICollectionViewFlowLayout = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumInteritemSpacing = spacingBetweenCell
layout.minimumLineSpacing = spacingBetweenCell
layout.sectionInset = .zero
layout.estimatedItemSize = pageItemCellSize
return layout
}()
private lazy var collectionView: UICollectionView = {
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
collectionView.isScrollEnabled = false
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.delegate = self
collectionView.dataSource = self
collectionView.showsHorizontalScrollIndicator = false
collectionView.showsVerticalScrollIndicator = false
collectionView.register(PaginationCellItem.self, forCellWithReuseIdentifier: PaginationCellItem.identifier)
collectionView.backgroundColor = .clear
return collectionView
}()
open override func initialSetup() {
super.initialSetup()
addSubview(containerView)
containerView.pinToSuperView()
containerView.widthAnchor.constraint(greaterThanOrEqualToConstant: 288).activate()
containerView.heightAnchor.constraint(equalToConstant: 44).activate()
containerView.addSubview(previousButton)
containerView.addSubview(collectionView)
containerView.addSubview(nextButton)
previousButton
.pinTop()
.pinBottom()
.pinLeading()
previousButton.trailingAnchor.constraint(greaterThanOrEqualTo: collectionView.leadingAnchor).activate()
collectionView.heightAnchor.constraint(equalToConstant: VDSLayout.Spacing.space4X.value).activate()
collectionView.centerYAnchor.constraint(equalTo: centerYAnchor).activate()
collectionView.centerXAnchor.constraint(equalTo: centerXAnchor).activate()
collectionView.trailingAnchor.constraint(greaterThanOrEqualTo: nextButton.leadingAnchor).activate()
collectionView.widthAnchor.constraint(equalToConstant: 92).activate()
nextButton
.pinTop()
.pinBottom()
.pinTrailing()
nextButton.onClick = onbuttonTapped
previousButton.onClick = onbuttonTapped
previousButton.isHidden = true
}
open override func updateView() {
super.updateView()
nextButton.surface = surface
previousButton.surface = surface
collectionView.reloadData()
}
private func onbuttonTapped(_ sender: UIButton) {
let isNextAction = sender == nextButton
if isNextAction {
_selectedPage += 1
} else {
_selectedPage -= 1
}
updateSelection()
}
private func updateSelection() {
let indexPath = IndexPath(row: selectedPage, section: 0)
collectionView.scrollToItem(at: indexPath, at: .left, animated: false)
previousButton.isHidden = selectedPage == 0
nextButton.isHidden = selectedPage == total - 1
collectionView.reloadData()
}
}
extension Pagination: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { total }
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PaginationCellItem.identifier, for: indexPath) as? PaginationCellItem else { return UICollectionViewCell() }
cell.update(selectedPage, currentIndex: indexPath.row, surface: surface)
return cell
}
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
_selectedPage = indexPath.row
updateSelection()
onPageDidSelect?(indexPath.row)
}
}