From 7a533944b81fce491d264a5766e21730d2fbd814 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 21 Mar 2024 11:17:44 -0500 Subject: [PATCH] refactored breadcrumbs to use selfsizing cv Signed-off-by: Matt Bruce --- VDS/Components/Breadcrumbs/Breadcrumbs.swift | 54 +++++++------------- 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/VDS/Components/Breadcrumbs/Breadcrumbs.swift b/VDS/Components/Breadcrumbs/Breadcrumbs.swift index ca6afaa1..ad2f20de 100644 --- a/VDS/Components/Breadcrumbs/Breadcrumbs.swift +++ b/VDS/Components/Breadcrumbs/Breadcrumbs.swift @@ -19,7 +19,7 @@ open class Breadcrumbs: View { // MARK: - Public Properties //-------------------------------------------------- /// Array of ``BreadcrumbItem`` views for the Breadcrumbs. - open var breadcrumbs: [BreadcrumbItem] = [] + open var breadcrumbs: [BreadcrumbItem] = [] { didSet { setNeedsUpdate() } } /// Array of ``BreadcurmbItemModel`` you are wanting to show. open var breadcrumbModels: [BreadcrumbItemModel] = [] { didSet { updateBreadcrumbItems() } } @@ -47,12 +47,7 @@ open class Breadcrumbs: View { //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- - // Sizes are from InVision design specs. - internal var containerSize: CGSize { CGSize(width: 45, height: 44) } - - internal var heightConstraint: NSLayoutConstraint? - - let layout: UICollectionViewFlowLayout = LeftAlignedCollectionViewFlowLayout().with { + let layout: UICollectionViewFlowLayout = BreadcrumbsFlowLayout().with { $0.estimatedItemSize = UICollectionViewFlowLayout.automaticSize $0.minimumInteritemSpacing = VDSLayout.Spacing.space1X.value $0.minimumLineSpacing = VDSLayout.Spacing.space1X.value @@ -61,8 +56,8 @@ open class Breadcrumbs: View { } ///Collectionview to render Breadcrumb Items - private lazy var collectionView: UICollectionView = { - let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + private lazy var collectionView: SelfSizingCollectionView = { + let collectionView = SelfSizingCollectionView(frame: .zero, collectionViewLayout: layout) collectionView.isScrollEnabled = false collectionView.translatesAutoresizingMaskIntoConstraints = false collectionView.delegate = self @@ -84,37 +79,26 @@ open class Breadcrumbs: View { breadcrumbItem.removeFromSuperview() } - breadcrumbs.removeAll() // Create new breadcrumb items from the models - for model in breadcrumbModels { + breadcrumbs = breadcrumbModels.compactMap({ model in let breadcrumbItem = BreadcrumbItem() breadcrumbItem.text = model.text - breadcrumbItem.link = model.link - breadcrumbItem.isSelected = model.isSelected ?? false - breadcrumbs.append(breadcrumbItem) + breadcrumbItem.isEnabled = model.enabled + breadcrumbItem.isSelected = model.selected breadcrumbItem.onClick = { [weak self] breadcrumb in - guard let self else { return } + guard let self, breadcrumb.isEnabled else { return } if self.onBreadcrumbShouldSelect?(breadcrumb) ?? true { model.onClick?(breadcrumb) self.onBreadcrumbDidSelect?(breadcrumb) } } - } - setNeedsUpdate() + return breadcrumbItem + }) } //------------------------------------------s-------- // MARK: - Overrides //-------------------------------------------------- - /// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations. - open override func setup() { - super.setup() - //create the wrapping view - heightConstraint = self.heightAnchor.constraint(equalToConstant: containerSize.height) - heightConstraint?.priority = .defaultHigh - heightConstraint?.isActive = true - } - /// Executed on initialization for this View. open override func initialSetup() { super.initialSetup() @@ -135,17 +119,17 @@ open class Breadcrumbs: View { open override func updateView() { super.updateView() collectionView.reloadData() - heightConstraint?.constant = collectionView.collectionViewLayout.collectionViewContentSize.height - heightConstraint?.isActive = true } open override func layoutSubviews() { - super.layoutSubviews() + //Don't call super since we don't want an infinite loop + //super.layoutSubviews() + // Accounts for any collection size changes DispatchQueue.main.async { [weak self] in guard let self else { return } self.collectionView.collectionViewLayout.invalidateLayout() - } + } } } @@ -153,17 +137,15 @@ extension Breadcrumbs: UICollectionViewDelegate, UICollectionViewDataSource { //-------------------------------------------------- // MARK: - UICollectionView Delegate & Datasource //-------------------------------------------------- - public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { breadcrumbs.count + public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + breadcrumbs.count } - + public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BreadcrumbCellItem.identifier, for: indexPath) as? BreadcrumbCellItem else { return UICollectionViewCell() } - let hideSlash = (indexPath.row == breadcrumbs.count - 1 || breadcrumbs.count == 1) + let hideSlash = indexPath.row == 0 cell.update(surface: surface, hideSlash: hideSlash, breadCrumbItem: breadcrumbs[indexPath.row]) return cell } - public func collectionView(_ collectionView: UICollectionView, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize { - breadcrumbs[indexPath.row].intrinsicContentSize - } }