diff --git a/Example/BrickKit-Example.xcodeproj/xcshareddata/xcschemes/BrickApp-iOS.xcscheme b/Example/BrickKit-Example.xcodeproj/xcshareddata/xcschemes/BrickApp-iOS.xcscheme index 05dc169..3f321b9 100644 --- a/Example/BrickKit-Example.xcodeproj/xcshareddata/xcschemes/BrickApp-iOS.xcscheme +++ b/Example/BrickKit-Example.xcodeproj/xcshareddata/xcschemes/BrickApp-iOS.xcscheme @@ -26,6 +26,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" shouldUseLaunchSchemeArgsEnv = "YES" codeCoverageEnabled = "YES"> @@ -56,6 +57,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Example/Source/Examples/Interactive/InvalidateHeightViewController.swift b/Example/Source/Examples/Interactive/InvalidateHeightViewController.swift index 802c702..0f53f91 100644 --- a/Example/Source/Examples/Interactive/InvalidateHeightViewController.swift +++ b/Example/Source/Examples/Interactive/InvalidateHeightViewController.swift @@ -26,15 +26,14 @@ class InvalidateHeightViewController: BrickViewController, HasTitle { self.view.backgroundColor = .brickBackground - self.registerBrickClass(LabelBrick.self) - - brick = LabelBrick(BrickIdentifiers.repeatLabel, backgroundColor: .brickGray1, dataSource: LabelBrickCellModel(text: "BRICK") { cell in + brick = LabelBrick(BrickIdentifiers.titleLabel, backgroundColor: .brickGray1, dataSource: LabelBrickCellModel(text: "BRICK") { cell in cell.configure() }) let section = BrickSection(bricks: [ brick, - LabelBrick(BrickIdentifiers.repeatLabel, backgroundColor: .brickGray2, dataSource: LabelBrickCellModel(text: "BRICK", configureCellBlock: LabelBrickCell.configure)) + LabelBrick(BrickIdentifiers.repeatLabel, backgroundColor: .brickGray2, dataSource: LabelBrickCellModel(text: "BRICK", configureCellBlock: LabelBrickCell.configure)), + brick, ], inset: 10, edgeInsets: UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)) self.setSection(section) @@ -55,12 +54,21 @@ class InvalidateHeightViewController: BrickViewController, HasTitle { } @objc func toggleHeights() { + let newHeight: BrickDimension switch brick.height { - case .fixed(_): brick.height = .auto(estimate: .fixed(size: 100)) - default: brick.height = .fixed(size: 200) + case .fixed(_): + newHeight = .auto(estimate: .fixed(size: 100)) + default: + newHeight = .fixed(size: 200) } - - self.brickCollectionView.invalidateBricks(false) + + let size = BrickSize(width: .ratio(ratio: 1), height: newHeight) + brick.size = size + + UIView.animate(withDuration: 2) { + self.brickCollectionView.invalidateBricks(false) + } + self.updateNavigationItem() } diff --git a/Source/Cells/BrickCell.swift b/Source/Cells/BrickCell.swift index 84eeb82..3db1507 100644 --- a/Source/Cells/BrickCell.swift +++ b/Source/Cells/BrickCell.swift @@ -96,7 +96,7 @@ open class BaseBrickCell: UICollectionViewCell { open lazy var topSeparatorLine: UIView = { return UIView() }() - + open override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) { super.apply(layoutAttributes) @@ -106,6 +106,7 @@ open class BaseBrickCell: UICollectionViewCell { // UICollectionView zIndex management 'fixes' the issue // http://stackoverflow.com/questions/12659301/uicollectionview-setlayoutanimated-not-preserving-zindex self.layer.zPosition = CGFloat(layoutAttributes.zIndex) + self.layoutIfNeeded() } open override func layoutSubviews() { @@ -200,7 +201,7 @@ open class BrickCell: BaseBrickCell { self.tapGesture = gesture addGestureRecognizer(gesture) } - + reloadContent() } @@ -213,17 +214,17 @@ open class BrickCell: BaseBrickCell { updateContent() self._brick.overrideContentSource?.overrideContent(for: self) } - + @objc func didTapCell() { _brick.brickCellTapDelegate?.didTapBrickCell(self) } - + open override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes { guard self._brick.height.isEstimate(withValue: nil) else { return layoutAttributes } - let preferred = layoutAttributes.copy() as! UICollectionViewLayoutAttributes + let preferred = layoutAttributes // We're inverting the frame because the given frame is already transformed var invertedFrame = layoutAttributes.frame.applying(layoutAttributes.transform.inverted()) @@ -246,4 +247,3 @@ open class BrickCell: BaseBrickCell { } } - diff --git a/Source/Layout/BrickFlowLayout.swift b/Source/Layout/BrickFlowLayout.swift index df4dd8b..fd8ed88 100644 --- a/Source/Layout/BrickFlowLayout.swift +++ b/Source/Layout/BrickFlowLayout.swift @@ -443,14 +443,8 @@ extension BrickFlowLayout: BrickLayoutSectionDataSource { var size: CGSize = .zero switch type { case .brick: - // Check if the attributes already had a height. If so, use that height - if attributes.frame.height != 0 && _dataSource.brickLayout(self, isEstimatedHeightFor: indexPath) { - let height = attributes.frame.size.height - size = CGSize(width: width, height: height) - } else { - let height = _dataSource.brickLayout(self, estimatedHeightForItemAt: indexPath, containedIn: width) - size = CGSize(width: width, height: height) - } + let height = _dataSource.brickLayout(self, estimatedHeightForItemAt: indexPath, containedIn: width) + size = CGSize(width: width, height: height) case .section(let section): let height = _dataSource.brickLayout(self, estimatedHeightForItemAt: indexPath, containedIn: width) if height == 0 { diff --git a/Source/ViewControllers/BrickCollectionView+BrickLayoutDataSource.swift b/Source/ViewControllers/BrickCollectionView+BrickLayoutDataSource.swift index d6f3807..05da283 100644 --- a/Source/ViewControllers/BrickCollectionView+BrickLayoutDataSource.swift +++ b/Source/ViewControllers/BrickCollectionView+BrickLayoutDataSource.swift @@ -41,6 +41,12 @@ extension BrickCollectionView: BrickLayoutDataSource { return 0 } + // If the brick height is an estimate, check if the cell is on screen + // If so, calculate the height directly, so the estimation is correct from the get-go + if brick.size.height.isEstimate(withValue: nil), let brickCell = self.cellForItem(at: indexPath) as? BrickCell { + return brickCell.heightForBrickView(withWidth: width) + } + let heightDimension = brick.size.height return heightDimension.value(for: width, startingAt: 0) } diff --git a/Source/ViewControllers/BrickCollectionView.swift b/Source/ViewControllers/BrickCollectionView.swift index b86da51..b41349e 100644 --- a/Source/ViewControllers/BrickCollectionView.swift +++ b/Source/ViewControllers/BrickCollectionView.swift @@ -231,10 +231,9 @@ open class BrickCollectionView: UICollectionView { if reloadSections { self.reloadSections(IndexSet(integersIn: 0..