vds_ios/VDS/Components/Pagination/PaginationFlowLayout.swift
Krishna Kishore Bandaru 9c8437fe6c Fixed layout issues
2024-03-13 22:28:52 +05:30

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)
}
}