92 lines
3.7 KiB
Swift
92 lines
3.7 KiB
Swift
//
|
|
// PaginationFlowLayout.swift
|
|
// VDS
|
|
//
|
|
// Created by Bandaru, Krishna Kishore on 06/03/24.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
|
|
///Customised flow layout for Pagination view
|
|
final class PaginationFlowLayout : UICollectionViewLayout {
|
|
//--------------------------------------------------
|
|
// MARK: - Private Properties
|
|
//--------------------------------------------------
|
|
///Spacing between the pagination cells
|
|
private let spacingBetweenCell: CGFloat = VDSLayout.Spacing.space1X.value
|
|
///Pre-defined sizes of the pagination cell based on number of digits.
|
|
private var upperLimitSize: CGSize {
|
|
switch upperLimitDigits {
|
|
case 1, 2: .init(width: 20, height: 16)
|
|
case 3: .init(width: 28, height: 16)
|
|
default: .init(width: 34, height: 16)
|
|
}
|
|
}
|
|
///Property to store the defined layout attributes.
|
|
private var itemCache : [UICollectionViewLayoutAttributes] = []
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Internal Properties
|
|
//--------------------------------------------------
|
|
///Maximum number of page indexes shown on UI
|
|
let maxNumberOfColumns: Int = 4
|
|
///Number of digits of the maximum page index.
|
|
var upperLimitDigits: Int = 0
|
|
///Number of page indexes shown on UI.
|
|
var numberOfColumns: Int = 4
|
|
///A property that publishes when there is change in collection view width.
|
|
@Published var collectionViewWidth: CGFloat = 0
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Overrides
|
|
//--------------------------------------------------
|
|
///Preparing the layout collection attributes for pagination and updating the collectionview width.
|
|
override func prepare() {
|
|
|
|
guard let collectionView else { return }
|
|
|
|
itemCache.removeAll()
|
|
var xPos : CGFloat = 0
|
|
for item in 0..<collectionView.numberOfItems(inSection: 0) {
|
|
let indexPath = IndexPath(item: item, section: 0)
|
|
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
|
|
attributes.frame = .init(origin: .init(x: xPos, y: 0), size: upperLimitSize)
|
|
xPos += (spacingBetweenCell + upperLimitSize.width)
|
|
itemCache.append(attributes)
|
|
}
|
|
guard !itemCache.isEmpty else { return }
|
|
var rightMostVisibleItem: UICollectionViewLayoutAttributes?
|
|
if numberOfColumns < itemCache.count {
|
|
rightMostVisibleItem = itemCache[max(numberOfColumns - 1, 0)]
|
|
} else {
|
|
rightMostVisibleItem = itemCache.last
|
|
}
|
|
if let rightMostVisibleItem {
|
|
collectionViewWidth = rightMostVisibleItem.frame.minX + rightMostVisibleItem.frame.width
|
|
}
|
|
}
|
|
|
|
///This will return the layout attributes for the elements in the defined rect
|
|
override func layoutAttributesForElements(in rect: CGRect)-> [UICollectionViewLayoutAttributes]? {
|
|
var visibleLayoutAttributes: [UICollectionViewLayoutAttributes] = []
|
|
for attributes in itemCache {
|
|
if attributes.frame.intersects(rect) {
|
|
visibleLayoutAttributes.append(attributes)
|
|
}
|
|
}
|
|
return visibleLayoutAttributes
|
|
}
|
|
|
|
///This will return the layout attributes at particular indexPath
|
|
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
|
|
return itemCache[indexPath.row]
|
|
}
|
|
|
|
///Returns the collectionview content size
|
|
override var collectionViewContentSize: CGSize {
|
|
guard let lastAttribute = itemCache.last else { return super.collectionViewContentSize }
|
|
return .init(width: lastAttribute.frame.width + lastAttribute.frame.origin.x, height: 16)
|
|
}
|
|
}
|