diff --git a/BrickKit.xcodeproj/project.pbxproj b/BrickKit.xcodeproj/project.pbxproj index b46e38f..50c7360 100644 --- a/BrickKit.xcodeproj/project.pbxproj +++ b/BrickKit.xcodeproj/project.pbxproj @@ -142,10 +142,6 @@ 9333538F1E36A37F003CEC85 /* GenericBrickTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9333538D1E36A37F003CEC85 /* GenericBrickTests.swift */; }; 933FF95E1DC1207900E0B80E /* Swizzle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 933FF95D1DC1207900E0B80E /* Swizzle.swift */; }; 933FF95F1DC1207900E0B80E /* Swizzle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 933FF95D1DC1207900E0B80E /* Swizzle.swift */; }; - 9340B6B21F4DBC2A005C28F0 /* BrickLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9340B6B11F4DBC2A005C28F0 /* BrickLogger.swift */; }; - 9340B6B31F4DBC2A005C28F0 /* BrickLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9340B6B11F4DBC2A005C28F0 /* BrickLogger.swift */; }; - 9340B6B51F4DE8F4005C28F0 /* BrickLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9340B6B41F4DE8F4005C28F0 /* BrickLoggerTests.swift */; }; - 9340B6B61F4DE8F4005C28F0 /* BrickLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9340B6B41F4DE8F4005C28F0 /* BrickLoggerTests.swift */; }; 934ADAA31E53B4B200C36587 /* ButtonBrick.xib in Resources */ = {isa = PBXBuildFile; fileRef = 934ADA971E53B48200C36587 /* ButtonBrick.xib */; }; 934ADAA41E53B4B200C36587 /* ImageBrick.xib in Resources */ = {isa = PBXBuildFile; fileRef = 934ADA9C1E53B49300C36587 /* ImageBrick.xib */; }; 934ADAA51E53B4B200C36587 /* LabelBrick.xib in Resources */ = {isa = PBXBuildFile; fileRef = 934ADA991E53B48C00C36587 /* LabelBrick.xib */; }; @@ -315,8 +311,6 @@ 933353891E368903003CEC85 /* GenericBrick.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GenericBrick.swift; path = Generic/GenericBrick.swift; sourceTree = ""; }; 9333538D1E36A37F003CEC85 /* GenericBrickTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenericBrickTests.swift; sourceTree = ""; }; 933FF95D1DC1207900E0B80E /* Swizzle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Swizzle.swift; sourceTree = ""; }; - 9340B6B11F4DBC2A005C28F0 /* BrickLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BrickLogger.swift; sourceTree = ""; }; - 9340B6B41F4DE8F4005C28F0 /* BrickLoggerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BrickLoggerTests.swift; sourceTree = ""; }; 934ADA971E53B48200C36587 /* ButtonBrick.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ButtonBrick.xib; sourceTree = ""; }; 934ADA991E53B48C00C36587 /* LabelBrick.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LabelBrick.xib; sourceTree = ""; }; 934ADA9C1E53B49300C36587 /* ImageBrick.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ImageBrick.xib; sourceTree = ""; }; @@ -774,7 +768,6 @@ 93D9EBE11DA4057000D8C87A /* BrickExtensions.swift */, 93D9EBE21DA4057000D8C87A /* BrickUtils.swift */, 93D9EBE31DA4057000D8C87A /* FatalError.swift */, - 9340B6B11F4DBC2A005C28F0 /* BrickLogger.swift */, ); path = Utils; sourceTree = ""; @@ -908,7 +901,6 @@ 9372C5061DA40735007D7EA1 /* FatalErrorTests.swift */, 93D9EC4E1DA4057900D8C87A /* XCTests.swift */, 933FF95D1DC1207900E0B80E /* Swizzle.swift */, - 9340B6B41F4DE8F4005C28F0 /* BrickLoggerTests.swift */, ); path = Utils; sourceTree = ""; @@ -1165,7 +1157,6 @@ 4E9A253B1DABEB9300D7EA99 /* BrickExtensions.swift in Sources */, 4E387C561DAEAB350087820E /* BrickAppearBehavior.swift in Sources */, 4E9A25331DABEB8800D7EA99 /* BrickLayoutSection.swift in Sources */, - 9340B6B31F4DBC2A005C28F0 /* BrickLogger.swift in Sources */, 4E9A25311DABEB8800D7EA99 /* BrickLayout.swift in Sources */, 4E9A25211DABEB6000D7EA99 /* MinimumStickyLayoutBehavior.swift in Sources */, 4E9A25301DABEB8800D7EA99 /* BrickFlowLayout.swift in Sources */, @@ -1245,7 +1236,6 @@ 4E9A254C1DABECDF00D7EA99 /* StickyFooterLayoutBehaviorTests.swift in Sources */, 4E9A256B1DABED0600D7EA99 /* TestBrickViewController.swift in Sources */, 4E9A255C1DABECF500D7EA99 /* BrickSelfsizingFlowLayoutTests.swift in Sources */, - 9340B6B61F4DE8F4005C28F0 /* BrickLoggerTests.swift in Sources */, 4E9A25501DABECE300D7EA99 /* ImageBrickTests.swift in Sources */, 932365731DF4FE1F00BE5183 /* BrickAlignmentTests.swift in Sources */, 4E387C571DAEAB380087820E /* BrickAppearBehaviorTests.swift in Sources */, @@ -1282,7 +1272,6 @@ 93D9EC0A1DA4057000D8C87A /* BrickLayoutInvalidationContext.swift in Sources */, 93F9B4D21DAD686E00927BE6 /* BrickAppearBehavior.swift in Sources */, 93D9EBF01DA4057000D8C87A /* OnScrollDownStickyLayoutBehavior.swift in Sources */, - 9340B6B21F4DBC2A005C28F0 /* BrickLogger.swift in Sources */, 93D9EC151DA4057000D8C87A /* BrickCollectionView+BrickLayoutDataSource.swift in Sources */, 93D9EC121DA4057000D8C87A /* BrickExtensions.swift in Sources */, 93D9EBE91DA4057000D8C87A /* CardLayoutBehavior.swift in Sources */, @@ -1329,7 +1318,6 @@ 93D9EC821DA4057900D8C87A /* DataSources.swift in Sources */, 93D9EC7D1DA4057900D8C87A /* BrickSectionDataSourceTests.swift in Sources */, 93D9EC5D1DA4057900D8C87A /* SpotlightLayoutBehaviorTests.swift in Sources */, - 9340B6B51F4DE8F4005C28F0 /* BrickLoggerTests.swift in Sources */, 9361309B1DB83CB7008FFFEF /* CustomBrickCollectionView.swift in Sources */, 93D9EC691DA4057900D8C87A /* DummyBrickWithoutNib.swift in Sources */, 93D9EC791DA4057900D8C87A /* BrickSelfsizingFlowLayoutTests.swift in Sources */, diff --git a/Source/Cells/BrickCell.swift b/Source/Cells/BrickCell.swift index e60556d..c30a342 100644 --- a/Source/Cells/BrickCell.swift +++ b/Source/Cells/BrickCell.swift @@ -62,7 +62,7 @@ open class BaseBrickCell: UICollectionViewCell { } // This value stores the expected width, so we can identify when this is met - private var requestedSize: CGSize = .zero + private var requestedWidth: CGFloat = 0 open func setContent(_ brick: Brick, index: Int, collectionIndex: Int, collectionIdentifier: String?) { self._brick = brick @@ -100,19 +100,23 @@ open class BaseBrickCell: UICollectionViewCell { open override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) { super.apply(layoutAttributes) - self.requestedSize = layoutAttributes.frame.size + self.requestedWidth = layoutAttributes.frame.width // Setting zPosition instead of relaying on // UICollectionView zIndex management 'fixes' the issue // http://stackoverflow.com/questions/12659301/uicollectionview-setlayoutanimated-not-preserving-zindex self.layer.zPosition = CGFloat(layoutAttributes.zIndex) + + if self is AsynchronousResizableCell { + self.layoutIfNeeded() + } } open override func layoutSubviews() { super.layoutSubviews() brickBackgroundView?.frame = self.bounds - if _brick != nil && frame.width == requestedSize.width { + if _brick != nil && frame.width == requestedWidth { self.layoutIfNeeded() // This layoutIfNeeded is added to make sure that the subviews are laid out correctly self.framesDidLayout() } @@ -177,17 +181,12 @@ open class BrickCell: BaseBrickCell { return UIEdgeInsetsMake(defaultTopConstraintConstant, defaultLeftConstraintConstant, defaultBottomConstraintConstant, defaultRightConstraintConstant) } - private var didUpdateEdgeInsets: Bool = false @objc open dynamic var edgeInsets: UIEdgeInsets = UIEdgeInsets.zero { didSet { - if edgeInsets == oldValue { - return - } self.topSpaceConstraint?.constant = edgeInsets.top self.bottomSpaceConstraint?.constant = edgeInsets.bottom self.leftSpaceConstraint?.constant = edgeInsets.left self.rightSpaceConstraint?.constant = edgeInsets.right - didUpdateEdgeInsets = true } } @@ -228,13 +227,6 @@ open class BrickCell: BaseBrickCell { return layoutAttributes } - if !didUpdateEdgeInsets { - guard let brickAttributes = layoutAttributes as? BrickLayoutAttributes, brickAttributes.isEstimateSize else { - return layoutAttributes - } - } - didUpdateEdgeInsets = false - let preferred = layoutAttributes // We're inverting the frame because the given frame is already transformed diff --git a/Source/Layout/BrickFlowLayout.swift b/Source/Layout/BrickFlowLayout.swift index 75c8bd9..fd8ed88 100644 --- a/Source/Layout/BrickFlowLayout.swift +++ b/Source/Layout/BrickFlowLayout.swift @@ -32,20 +32,6 @@ fileprivate func >= (lhs: T?, rhs: T?) -> Bool { /// BrickFlowLayoutiis a UICollectionViewLayout that can handle behaviors open class BrickFlowLayout: UICollectionViewLayout, BrickLayout { - var isDirty: Bool { - get { - return !dirtyMap.isEmpty - } - set { - if !newValue { - dirtyMap.removeAll() - dirtyIndexPaths.removeAll() - } - } - } - var dirtyMap: [Int: Int] = [:] - var dirtyIndexPaths: [IndexPath] = [] - // Mark: - Public members open override var description: String { @@ -298,25 +284,7 @@ extension BrickFlowLayout { return contentSize } - func updateDirtyBricks(updatedAttributes: @escaping OnAttributesUpdatedHandler) { - for (section, item) in dirtyMap { - let layoutSection = sections![section]! - layoutSection.createOrUpdateCells(from: item, invalidate: false, updatedAttributes: updatedAttributes) - if let sectionAttributes = layoutSection.sectionAttributes { - invalidateHeight(for: sectionAttributes.indexPath, updatedAttributes: updatedAttributes) - } - } - - recalculateContentSize() - dirtyIndexPaths.forEach { indexPath in - delegate?.brickLayout(self, didUpdateHeightForItemAtIndexPath: indexPath) - } - - isDirty = false - } - open override func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) { - BrickLogger.logVerbose(message: "Invalidate layout with context \(context)") guard sections != nil else { // No need to invalidate if there are no sections super.invalidateLayout(with: context) return @@ -384,21 +352,7 @@ extension BrickFlowLayout { } let shouldInvalidate = preferredAttributes.frame.height != brickAttribute.originalFrame.height brickAttribute.isEstimateSize = false - -// return shouldInvalidate - if shouldInvalidate { - let indexPath = preferredAttributes.indexPath - sections![indexPath.section]?.update(height: preferredAttributes.frame.height, at: indexPath.item, continueCalculation: false, updatedAttributes: nil) - if let current = dirtyMap[indexPath.section] { - if indexPath.item < current { - dirtyMap[indexPath.section] = indexPath.item - } - } else { - dirtyMap[indexPath.section] = indexPath.item - } - dirtyIndexPaths.append(indexPath) - } - return false + return shouldInvalidate } open override func invalidationContext(forPreferredLayoutAttributes preferredAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes originalAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutInvalidationContext { @@ -533,7 +487,7 @@ extension BrickFlowLayout: BrickLayoutInvalidationProvider { let contentOffsetAdjustment = shouldAdjustContentOffset ? height - firstAttributes.frame.height : 0 updateSection(section, updatedAttributes: updatedAttributes) { - section.update(height: height, at: indexPath.item, continueCalculation: true, updatedAttributes: { attributes, oldFrame in + section.update(height: height, at: indexPath.item, updatedAttributes: { attributes, oldFrame in updatedAttributes(attributes, oldFrame) self.attributesWereUpdated(attributes, oldFrame: oldFrame, fromBehaviors: false, updatedAttributes: updatedAttributes) }) @@ -590,7 +544,6 @@ extension BrickFlowLayout: BrickLayoutInvalidationProvider { self.contentSize = contentSize } - @discardableResult func recalculateContentSize() -> CGSize { let oldContentSize = self.contentSize contentSize = sections?[0]?.frame.size ?? CGSize.zero diff --git a/Source/Layout/BrickLayoutInvalidationContext.swift b/Source/Layout/BrickLayoutInvalidationContext.swift index 6a98728..368a2e2 100644 --- a/Source/Layout/BrickLayoutInvalidationContext.swift +++ b/Source/Layout/BrickLayoutInvalidationContext.swift @@ -17,7 +17,6 @@ enum BrickLayoutInvalidationContextType { case behaviorsChanged case invalidate case updateVisibility - case updateDirtyBricks /** Flag that indicates if all attributes should be invalidated. @@ -26,7 +25,7 @@ enum BrickLayoutInvalidationContextType { */ var shouldInvalidateAllAttributes: Bool { switch self { - case .rotation, .invalidate, .creation, .updateVisibility, .updateDirtyBricks /*, .updateHeight(_) */: return true + case .rotation, .invalidate, .creation, .updateVisibility, .updateHeight(_): return true default: return false } } @@ -45,7 +44,6 @@ protocol BrickLayoutInvalidationProvider: class { func registerUpdatedAttributes(_ attributes: BrickLayoutAttributes, oldFrame: CGRect?, fromBehaviors: Bool, updatedAttributes: @escaping OnAttributesUpdatedHandler) func applyHideBehavior(updatedAttributes: @escaping OnAttributesUpdatedHandler) func updateContentSize(_ contentSize: CGSize) - func updateDirtyBricks(updatedAttributes: @escaping OnAttributesUpdatedHandler) } extension BrickLayoutInvalidationContext { @@ -107,8 +105,6 @@ class BrickLayoutInvalidationContext: UICollectionViewLayoutInvalidationContext self.invalidateSections(provider, layout: layout) case .updateVisibility: self.applyHideBehaviors(provider, updatedAttributes: updateAttributes) - case .updateDirtyBricks: - provider.updateDirtyBricks(updatedAttributes: updateAttributes) default: break } @@ -160,17 +156,14 @@ class BrickLayoutInvalidationContext: UICollectionViewLayoutInvalidationContext } func handleAttributes(_ attributes: BrickLayoutAttributes, oldFrame: CGRect?, provider: BrickLayoutInvalidationProvider, layout: UICollectionViewLayout, fromBehaviors: Bool) { - if !type.shouldInvalidateAllAttributes { - if !updatedAttributes.contains(attributes) { - updatedAttributes.append(attributes) - } - } + if !updatedAttributes.contains(attributes) { + updatedAttributes.append(attributes) + } + provider.registerUpdatedAttributes(attributes, oldFrame: oldFrame, fromBehaviors: fromBehaviors, updatedAttributes: { attributes, oldFrame in - if !self.type.shouldInvalidateAllAttributes { - if !self.updatedAttributes.contains(attributes) { - self.updatedAttributes.append(attributes) - } + if !self.updatedAttributes.contains(attributes) { + self.updatedAttributes.append(attributes) } }) } diff --git a/Source/Layout/BrickLayoutSection.swift b/Source/Layout/BrickLayoutSection.swift index 863c1ed..3d2529b 100644 --- a/Source/Layout/BrickLayoutSection.swift +++ b/Source/Layout/BrickLayoutSection.swift @@ -239,20 +239,18 @@ internal class BrickLayoutSection { attributes.frame.size.width = 0 } - func update(height: CGFloat, at index: Int, continueCalculation: Bool, updatedAttributes: OnAttributesUpdatedHandler?) { + func update(height: CGFloat, at index: Int, updatedAttributes: OnAttributesUpdatedHandler?) { guard let brickAttributes = attributes[index] else { return } brickAttributes.isEstimateSize = false -// guard brickAttributes.originalFrame.height != height else { -// return -// } + guard brickAttributes.originalFrame.height != height else { + return + } brickAttributes.originalFrame.size.height = height - if continueCalculation { - createOrUpdateCells(from: index, invalidate: false, updatedAttributes: updatedAttributes) - } + createOrUpdateCells(from: index, invalidate: false, updatedAttributes: updatedAttributes) } func invalidate(at index: Int, updatedAttributes: OnAttributesUpdatedHandler?) { @@ -309,7 +307,7 @@ internal class BrickLayoutSection { /// - firstIndex: The index the calculation needs to start from (the main reason is to just calculate the next cells /// - invalidate: Identifies if the attributes need to be invalidated (reset height etc) /// - updatedAttributes: Callback for the attributes that have been updated - public func createOrUpdateCells(from firstIndex: Int, invalidate: Bool, updatedAttributes: OnAttributesUpdatedHandler?) { + fileprivate func createOrUpdateCells(from firstIndex: Int, invalidate: Bool, updatedAttributes: OnAttributesUpdatedHandler?) { guard let dataSource = dataSource else { return @@ -403,10 +401,10 @@ internal class BrickLayoutSection { frame.size.width = x + edgeInsets.right } -// if attributes.count < 100 { -// // Prevent that the "Huge" test aren't taking forever to complete -// BrickLogger.logVerbose(message: self.printAttributes()) -// } + + if brickDebug { + printAttributes() + } } /// To continue calculating, it needs to start from a certain origin. To make sure that the rows are @@ -574,21 +572,19 @@ internal class BrickLayoutSection { return rowAttributes } - func printAttributes() -> String { - var debugString = "" - debugString += "\n" - debugString += "Attributes for section \(sectionIndex) in \(dataSource!)" - debugString += "\n" - debugString += "Number of attributes: \(attributes.count) in frameOfInterest \(_dataSource.frameOfInterest)" - debugString += "\n" - debugString += "Total Frame: \(self.frame)" - debugString += "\n" + func printAttributes() { + guard attributes.count < 100 else { + // Prevent that the "Huge" test aren't taking forever to complete + return + } + BrickUtils.print("\n") + BrickUtils.print("Attributes for section \(sectionIndex) in \(String(describing: dataSource))") + BrickUtils.print("Number of attributes: \(attributes.count) in \(_dataSource.frameOfInterest)") + BrickUtils.print("Frame: \(self.frame)") let keys = attributes.keys.sorted(by: <) for key in keys { - debugString += "\(key): \(attributes[key]!)" - debugString += "\n" + BrickUtils.print("\(key): \(attributes[key]!)") } - return debugString } /// Create or update 1 cell @@ -765,10 +761,11 @@ extension BrickLayoutSection { attributes.append(brickAttributes) } return true + } else { + // if the frame is not the same as the originalFrame, continue checking because the attribute could be offscreen + return brickAttributes.frame != brickAttributes.originalFrame } - // if the frame is not the same as the originalFrame, continue checking because the attribute could be offscreen - return brickAttributes.frame != brickAttributes.originalFrame } // Go back to see if previous attributes are not closer diff --git a/Source/Utils/BrickLogger.swift b/Source/Utils/BrickLogger.swift deleted file mode 100644 index 9bf6eb9..0000000 --- a/Source/Utils/BrickLogger.swift +++ /dev/null @@ -1,54 +0,0 @@ -// -// BrickLogger.swift -// BrickKit -// -// Created by Ruben Cagnie on 8/23/17. -// Copyright © 2017 Wayfair. All rights reserved. -// - -import UIKit - -public class BrickLogger { - public static var logger: BrickLoggable? - - internal static func logError(message: @escaping @autoclosure() -> String, file: String = #file, on lineNumber: Int = #line) { - BrickLogger.logger?.logError(message: message, file: file, lineNumber: lineNumber) - } - - internal static func logVerbose(message: @escaping @autoclosure() -> String, file: String = #file, on lineNumber: Int = #line) { - BrickLogger.logger?.logVerbose(message: message, file: file, lineNumber: lineNumber) - } - - internal static func logWarning(message: @escaping @autoclosure() -> String, file: String = #file, on lineNumber: Int = #line) { - BrickLogger.logger?.logWarning(message: message, file: file, lineNumber: lineNumber) - } -} - -public protocol BrickLoggable { - func logError(message: @escaping @autoclosure() -> String, file: String, lineNumber: Int) - func logVerbose(message: @escaping @autoclosure() -> String, file: String, lineNumber: Int) - func logWarning(message: @escaping @autoclosure() -> String, file: String, lineNumber: Int) -} - -public class BrickConsoleLogger: BrickLoggable { - let logVerbose: Bool - - public init(logVerbose: Bool = false) { - self.logVerbose = logVerbose - } - - public func logError(message: @escaping @autoclosure() -> String, file: String, lineNumber: Int) { - print("ERROR [\((file as NSString).lastPathComponent):\(lineNumber)]: \(message())") - } - - public func logVerbose(message: @escaping @autoclosure() -> String, file: String, lineNumber: Int) { - if logVerbose { - print("VERBOSE [\((file as NSString).lastPathComponent):\(lineNumber)]: \(message())") - } - } - - public func logWarning(message: @escaping @autoclosure() -> String, file: String, lineNumber: Int) { - print("WARNING [\((file as NSString).lastPathComponent):\(lineNumber)]: \(message())") - } - -} diff --git a/Source/Utils/BrickUtils.swift b/Source/Utils/BrickUtils.swift index 104f729..21a240b 100644 --- a/Source/Utils/BrickUtils.swift +++ b/Source/Utils/BrickUtils.swift @@ -8,6 +8,8 @@ import Foundation +let brickDebug = false + enum BrickUtils { /// Calculates a width, based on the total width and its inset @@ -23,5 +25,11 @@ enum BrickUtils { let width = rowWidth * (ratio / widthRatio) return width } + + public static func print(_ message: String) { + if brickDebug { + Swift.print(message) + } + } } diff --git a/Source/ViewControllers/BrickCollectionView.swift b/Source/ViewControllers/BrickCollectionView.swift index 92d498c..8ed184d 100644 --- a/Source/ViewControllers/BrickCollectionView.swift +++ b/Source/ViewControllers/BrickCollectionView.swift @@ -98,13 +98,6 @@ open class BrickCollectionView: UICollectionView { register(BrickSectionCell.self, forCellWithReuseIdentifier: BrickSection.nibName) } - open override func layoutSubviews() { - super.layoutSubviews() - if layout.isDirty { - self.layout.invalidateLayout(with: BrickLayoutInvalidationContext(type: .updateDirtyBricks)) - } - } - // MARK: - Setting up the models /// Sets the section for the BrickCollectionView @@ -172,7 +165,7 @@ open class BrickCollectionView: UICollectionView { } if isConfiguringCollectionBrick { - BrickLogger.logWarning(message: "calling `registerBrickClass` in `configure(for cell: CollectionBrickCell)` is deprecated. Use `registerBricks(for cell: CollectionBrickCell)` or `CollectionBrickCell(brickTypes: [Brick.Type])`. This will be a fatalError in a future release") + BrickUtils.print("calling `registerBrickClass` in `configure(for cell: CollectionBrickCell)` is deprecated. Use `registerBricks(for cell: CollectionBrickCell)` or `CollectionBrickCell(brickTypes: [Brick.Type])`. This will be a fatalError in a future release") } registeredBricks[identifier] = cellIdentifier @@ -186,7 +179,7 @@ open class BrickCollectionView: UICollectionView { self.register(nib, forCellWithReuseIdentifier: cellIdentifier) if isConfiguringCollectionBrick { - BrickLogger.logWarning(message: "calling `registerNib` in `configure(for cell: CollectionBrickCell)` is deprecated. Use `registerBricks(for cell: CollectionBrickCell)`. This will be a fatalError in a future release") + BrickUtils.print("calling `registerNib` in `configure(for cell: CollectionBrickCell)` is deprecated. Use `registerBricks(for cell: CollectionBrickCell)`. This will be a fatalError in a future release") } registeredBricks[CustomNibPrefix + identifier] = cellIdentifier diff --git a/Tests/Behaviors/StickyFooterLayoutBehaviorTests.swift b/Tests/Behaviors/StickyFooterLayoutBehaviorTests.swift index ddd52f0..5371ab2 100644 --- a/Tests/Behaviors/StickyFooterLayoutBehaviorTests.swift +++ b/Tests/Behaviors/StickyFooterLayoutBehaviorTests.swift @@ -248,7 +248,8 @@ class StickyFooterLayoutBehaviorTests: BrickFlowLayoutBaseTests { let repeatCountDataSource = FixedRepeatCountDataSource(repeatCountHash: ["BRICK" : 50]) section.repeatCountDataSource = repeatCountDataSource - collectionView.setupSectionAndLayout(section) + collectionView.setSection(section) + collectionView.layoutSubviews() let attributes = collectionView.collectionViewLayout.layoutAttributesForItem(at: IndexPath(item: 50, section: 1)) XCTAssertEqual(attributes?.frame, CGRect(x: 0, y: 404, width: 320, height: 76)) diff --git a/Tests/Bricks/ButtonBrickTests.swift b/Tests/Bricks/ButtonBrickTests.swift index b06026a..4726d29 100644 --- a/Tests/Bricks/ButtonBrickTests.swift +++ b/Tests/Bricks/ButtonBrickTests.swift @@ -32,11 +32,13 @@ class ButtonBrickTests: XCTestCase { } func setupSection(_ buttonBrick: ButtonBrick) -> ButtonBrickCell? { + brickCollectionView.registerBrickClass(ButtonBrick.self) self.buttonBrick = buttonBrick let section = BrickSection(bricks: [ buttonBrick ]) - brickCollectionView.setupSectionAndLayout(section) + brickCollectionView.setSection(section) + brickCollectionView.layoutSubviews() return buttonCell } diff --git a/Tests/Bricks/CollectionBrickTests.swift b/Tests/Bricks/CollectionBrickTests.swift index 264eccf..0594188 100644 --- a/Tests/Bricks/CollectionBrickTests.swift +++ b/Tests/Bricks/CollectionBrickTests.swift @@ -66,7 +66,8 @@ class CollectionBrickTests: XCTestCase { cell.brickCollectionView.registerBrickClass(DummyBrick.self) })) ], edgeInsets: UIEdgeInsets(top: 300, left: 0, bottom: 0, right: 0)) - brickView.setupSectionAndLayout(section) + brickView.setSection(section) + brickView.layoutSubviews() let cell1 = brickView.cellForItem(at: IndexPath(item: 0, section: 1)) as? CollectionBrickCell XCTAssertEqual(cell1?.frame, CGRect(x: 0, y: 300, width: 320, height: 200)) @@ -123,7 +124,8 @@ class CollectionBrickTests: XCTestCase { let delegate = FixedBrickLayoutDelegate() brickView.layout.delegate = delegate - brickView.setupSectionAndLayout(section) + brickView.setSection(section) + brickView.layoutSubviews() XCTAssertEqual(delegate.count, 1, "The delegate should have only been called 1 time for the updated height of the CollectionBrick") } diff --git a/Tests/Bricks/ImageBrickTests.swift b/Tests/Bricks/ImageBrickTests.swift index 16dc6f5..c65235b 100644 --- a/Tests/Bricks/ImageBrickTests.swift +++ b/Tests/Bricks/ImageBrickTests.swift @@ -80,7 +80,8 @@ class ImageBrickTests: XCTestCase { let section = BrickSection(bricks: [ ImageBrick(dataSource: ImageBrickModel(image: image, contentMode: .scaleAspectFill)), ]) - brickView.setupSectionAndLayout(section) + brickView.setSection(section) + brickView.layoutSubviews() let cell1 = brickView.cellForItem(at: IndexPath(item: 0, section: 1)) as? ImageBrickCell cell1?.layoutIfNeeded() @@ -96,7 +97,8 @@ class ImageBrickTests: XCTestCase { let section = BrickSection(bricks: [ ImageBrick(dataSource: ImageBrickModel(image: image, contentMode: .scaleAspectFit)), ]) - brickView.setupSectionAndLayout(section) + brickView.setSection(section) + brickView.layoutSubviews() let cell1 = brickView.cellForItem(at: IndexPath(item: 0, section: 1)) as? ImageBrickCell cell1?.layoutIfNeeded() @@ -111,7 +113,8 @@ class ImageBrickTests: XCTestCase { let section = BrickSection(bricks: [ ImageBrick(dataSource: ImageBrickModel(image: image, contentMode: .scaleToFill)), ]) - brickView.setupSectionAndLayout(section) + brickView.setSection(section) + brickView.layoutSubviews() let cell1 = brickView.cellForItem(at: IndexPath(item: 0, section: 1)) as? ImageBrickCell cell1?.layoutIfNeeded() @@ -321,7 +324,6 @@ class ImageBrickTests: XCTestCase { let expectationDidUpdate: XCTestExpectation = self.expectation(description: "testURLSetOnOtherQueue - Wait for image to download") delegate.didUpdateHandler = { DispatchQueue.main.async { - self.brickView.layoutIfNeeded() let ratio:CGFloat = 378.0 / 659.0 XCTAssertTrue(delegate.didUpdateCalled) XCTAssertEqualWithAccuracy(cell2!.frame.height, 320 * ratio, accuracy: 0.5) diff --git a/Tests/Bricks/LabelBrickTests.swift b/Tests/Bricks/LabelBrickTests.swift index e7abbb9..8eb1883 100644 --- a/Tests/Bricks/LabelBrickTests.swift +++ b/Tests/Bricks/LabelBrickTests.swift @@ -34,11 +34,13 @@ class LabelBrickTests: XCTestCase { } func setupSection(_ labelBrick: LabelBrick) -> LabelBrickCell? { + brickCollectionView.registerBrickClass(LabelBrick.self) self.labelBrick = labelBrick let section = BrickSection(bricks: [ labelBrick ]) - brickCollectionView.setupSectionAndLayout(section) + brickCollectionView.setSection(section) + brickCollectionView.layoutSubviews() return labelCell } diff --git a/Tests/Cells/AsynchronousResizableCellTests.swift b/Tests/Cells/AsynchronousResizableCellTests.swift index 0589a6a..b5e3d43 100644 --- a/Tests/Cells/AsynchronousResizableCellTests.swift +++ b/Tests/Cells/AsynchronousResizableCellTests.swift @@ -208,6 +208,7 @@ class AsynchronousResizableCellTests: XCTestCase { } func testResizingInCollectionBrickScrolling() { + brickView.registerBrickClass(CollectionBrick.self) let collectionSection = BrickSection(bricks: [ DummyBrick(width: .ratio(ratio: 1/2)), @@ -223,7 +224,9 @@ class AsynchronousResizableCellTests: XCTestCase { })) ]) - brickView.setupSectionAndLayout(section) + + brickView.setSection(section) + brickView.layoutSubviews() let cell = brickView.cellForItem(at: IndexPath(item: 0, section: 1)) as? CollectionBrickCell cell?.brickCollectionView.contentOffset.x = 2 * brickView.frame.width diff --git a/Tests/Layout/BrickFlowLayoutSectionTests.swift b/Tests/Layout/BrickFlowLayoutSectionTests.swift index f89e2a5..1f3eaf8 100644 --- a/Tests/Layout/BrickFlowLayoutSectionTests.swift +++ b/Tests/Layout/BrickFlowLayoutSectionTests.swift @@ -327,7 +327,8 @@ class BrickFlowLayoutSectionTests: BrickFlowLayoutBaseTests { LabelBrick(width: .ratio(ratio: 0.5), text: "BRICK"), LabelBrick("THIS ONE", text: "BRICK"), ], inset: 10, edgeInsets: UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)) - collectionView.setupSectionAndLayout(section) + collectionView.setSection(section) + collectionView.layoutSubviews() XCTAssertEqual(layout.layoutAttributesForItem(at: IndexPath(item: 0, section: 1))?.frame, CGRect(x: 20, y: 20, width: 135, height: 17)) diff --git a/Tests/Layout/BrickFlowLayoutTests.swift b/Tests/Layout/BrickFlowLayoutTests.swift index eb120c2..f8fdd4a 100644 --- a/Tests/Layout/BrickFlowLayoutTests.swift +++ b/Tests/Layout/BrickFlowLayoutTests.swift @@ -199,6 +199,7 @@ class BrickFlowLayoutTests: BrickFlowLayoutBaseTests { func testDelegate() { let brickView = BrickCollectionView(frame: CGRect(x: 0, y: 0, width: 320, height: 480)) + brickView.registerBrickClass(DummyBrick.self) let delegate = FixedDelegate() brickView.layout.delegate = delegate @@ -206,7 +207,8 @@ class BrickFlowLayoutTests: BrickFlowLayoutBaseTests { let section = BrickSection(bricks: [ DummyBrick() ]) - brickView.setupSectionAndLayout(section) + brickView.setSection(section) + brickView.layoutSubviews() XCTAssertTrue(delegate.didUpdateCalled) XCTAssertEqual(delegate.updatedIndexPaths, [IndexPath(item: 0, section: 1)]) diff --git a/Tests/Layout/BrickLayoutSectionTests.swift b/Tests/Layout/BrickLayoutSectionTests.swift index 71e2e75..975f466 100644 --- a/Tests/Layout/BrickLayoutSectionTests.swift +++ b/Tests/Layout/BrickLayoutSectionTests.swift @@ -125,7 +125,7 @@ class BrickLayoutSectionTests: XCTestCase { XCTAssertEqual(createdIndexPaths.count, 4) - section.update(height: 20, at: 0, continueCalculation: true, updatedAttributes: { attributes, _ in + section.update(height: 20, at: 0, updatedAttributes: { attributes, _ in updatedIndexPaths.append(attributes.indexPath) }) @@ -146,7 +146,7 @@ class BrickLayoutSectionTests: XCTestCase { let section = createSection([third, third, third, third, third], heights: [50, 50, 50, 50, 50], edgeInsets: UIEdgeInsets(top: 10, left: 5, bottom: 10, right: 5), inset: 5, sectionWidth: 320) var updatedIndexPaths: [IndexPath] = [] - section.update(height: 20, at: 2, continueCalculation: true, updatedAttributes: { attributes, _ in + section.update(height: 20, at: 2, updatedAttributes: { attributes, _ in updatedIndexPaths.append(attributes.indexPath) }) XCTAssertEqual(updatedIndexPaths.count, 3) @@ -166,7 +166,7 @@ class BrickLayoutSectionTests: XCTestCase { let section = createSection([third, third, third, third, third], heights: [50, 50, 50, 50, 50], edgeInsets: UIEdgeInsets(top: 10, left: 5, bottom: 10, right: 5), inset: 5, sectionWidth: 320) var updatedIndexPaths: [IndexPath] = [] - section.update(height: 80, at: 2, continueCalculation: true, updatedAttributes: { attributes, _ in + section.update(height: 80, at: 2, updatedAttributes: { attributes, _ in updatedIndexPaths.append(attributes.indexPath) }) XCTAssertEqual(updatedIndexPaths.count, 3) @@ -186,7 +186,7 @@ class BrickLayoutSectionTests: XCTestCase { let section = createSection([third, third, third, third, third], heights: [50, 50, 50, 50, 50], edgeInsets: UIEdgeInsets(top: 10, left: 5, bottom: 10, right: 5), inset: 5, sectionWidth: 320) var updatedIndexPaths: [IndexPath] = [] - section.update(height: 80, at: 5, continueCalculation: true, updatedAttributes: { attributes, _ in + section.update(height: 80, at: 5, updatedAttributes: { attributes, _ in updatedIndexPaths.append(attributes.indexPath) }) XCTAssertEqual(updatedIndexPaths.count, 0) diff --git a/Tests/Utils/BrickLoggerTests.swift b/Tests/Utils/BrickLoggerTests.swift deleted file mode 100644 index 8abe8c6..0000000 --- a/Tests/Utils/BrickLoggerTests.swift +++ /dev/null @@ -1,62 +0,0 @@ -// -// BrickLoggerTests.swift -// BrickKit -// -// Created by Ruben Cagnie on 8/23/17. -// Copyright © 2017 Wayfair. All rights reserved. -// - -import XCTest -@testable import BrickKit - -class TestLogger: BrickLoggable { - var didPrintWarning: Bool = false - var didPrintVerbose: Bool = false - var didPrintError: Bool = false - - public func logError(message: @escaping @autoclosure() -> String, file: String, lineNumber: Int) { - didPrintError = true - } - - public func logVerbose(message: @escaping @autoclosure() -> String, file: String, lineNumber: Int) { - didPrintVerbose = true - } - - public func logWarning(message: @escaping @autoclosure() -> String, file: String, lineNumber: Int) { - didPrintWarning = true - } - -} - -class BrickLoggerTests: XCTestCase { - var testLogger: TestLogger! - - override func setUp() { - super.setUp() - - testLogger = TestLogger() - BrickLogger.logger = testLogger - } - - override func tearDown() { - super.tearDown() - - BrickLogger.logger = nil - } - - func testThatErrorGetsLogged() { - BrickLogger.logError(message: "Some error") - XCTAssertTrue(testLogger.didPrintError) - } - - func testThatWarningGetsLogged() { - BrickLogger.logWarning(message: "Some warning") - XCTAssertTrue(testLogger.didPrintWarning) - } - - func testThatVerboseGetsLogged() { - BrickLogger.logVerbose(message: "Some verbose") - XCTAssertTrue(testLogger.didPrintVerbose) - } - -} diff --git a/Tests/Utils/XCTests.swift b/Tests/Utils/XCTests.swift index 92bc960..bd4da59 100644 --- a/Tests/Utils/XCTests.swift +++ b/Tests/Utils/XCTests.swift @@ -55,12 +55,12 @@ extension XCTest { func verifyAttributesToExpectedResult(_ attributes: [UICollectionViewLayoutAttributes], map: @escaping ((_ attribute: UICollectionViewLayoutAttributes) -> T), expectedResult: [Int: [T]], sort: ((T, T) -> Bool)? = nil) -> Bool { let array = simpleArrayWithFramesForCollectionViewAttributes(attributes, map: map) - BrickLogger.logVerbose(message: "Actual: \(array)") - BrickLogger.logVerbose(message: "Expected: \(expectedResult)") + BrickUtils.print("Actual: \(array)") + BrickUtils.print("Expected: \(expectedResult)") guard Array(expectedResult.keys.sorted()) == Array(array.keys.sorted()) else { - BrickLogger.logVerbose(message: "Keys are not the same") - BrickLogger.logVerbose(message: "Keys: \(Array(array.keys.sorted()))") - BrickLogger.logVerbose(message: "Expected Keys: \(Array(expectedResult.keys.sorted()))") + BrickUtils.print("Keys are not the same") + BrickUtils.print("Keys: \(Array(array.keys.sorted()))") + BrickUtils.print("Expected Keys: \(Array(expectedResult.keys.sorted()))") return false } @@ -74,12 +74,12 @@ extension XCTest { } if frames != expectedFrames { - BrickLogger.logVerbose(message: "\(section) not equal") - BrickLogger.logVerbose(message: "Frames: \(frames)") - BrickLogger.logVerbose(message: "ExpectedFrames: \(expectedFrames)") + BrickUtils.print("\(section) not equal") + BrickUtils.print("Frames: \(frames)") + BrickUtils.print("ExpectedFrames: \(expectedFrames)") return false } else { - BrickLogger.logVerbose(message: "\(section) equal") + BrickUtils.print("\(section) equal") } } return true @@ -131,6 +131,5 @@ extension BrickCollectionView { func setupSectionAndLayout(_ section: BrickSection) { self.setSection(section) self.layoutSubviews() - self.layoutIfNeeded() // We need to do this layoutIfNeeded, because of the new invalidation on height calculation } } diff --git a/Tests/ViewControllers/BrickCollectionViewTests.swift b/Tests/ViewControllers/BrickCollectionViewTests.swift index 1c21ca5..7bb895b 100644 --- a/Tests/ViewControllers/BrickCollectionViewTests.swift +++ b/Tests/ViewControllers/BrickCollectionViewTests.swift @@ -407,7 +407,6 @@ class BrickCollectionViewTests: XCTestCase { } waitForExpectations(timeout: 5, handler: nil) brickView.layoutSubviews() - brickView.layoutIfNeeded() cell = brickView.cellForItem(at: IndexPath(item: 0, section: 1)) as? CollectionBrickCell XCTAssertEqual(cell?.frame, CGRect(x: 0, y: 0, width: 320, height: 100))