-
Notifications
You must be signed in to change notification settings - Fork 1
Rd/pinterest #40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Senbazuru1075
wants to merge
10
commits into
master
Choose a base branch
from
rd/pinterest
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Rd/pinterest #40
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
c0152fe
finished Lux
Senbazuru1075 8b2f9dd
finished making the layout more robust
Senbazuru1075 1e0d353
Added a test
Senbazuru1075 25f4a0a
finished pinterest
Senbazuru1075 ba1bd5e
fixed issues
Senbazuru1075 a6a1318
fixed issues
Senbazuru1075 41a570a
added requested functionality
Senbazuru1075 3ad336d
finsihed
Senbazuru1075 2ca7029
added width functionality
Senbazuru1075 11b9077
Added Requested Functionality
Senbazuru1075 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -60,4 +60,5 @@ class ListViewModelTests: XCTestCase { | |
| XCTAssert(wasFiltered) | ||
| cancel.cancel() | ||
| } | ||
|
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
159 changes: 159 additions & 0 deletions
159
LUX/Classes/Base/CollectionViews/LUXPinterestStyleLayout.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| // | ||
| // LUXPinterestStyleLayout.swift | ||
| // LUX | ||
| // | ||
| // Created by Remmington Damper on 12/12/21. | ||
| // | ||
|
|
||
| import UIKit | ||
|
|
||
|
|
||
| public class LUXPinterestStyleLayout: UICollectionViewLayout { | ||
| private var _columnCount: Int? { didSet { invalidateLayout() }} | ||
| public func setColumnCount(_ count: Int) { _columnCount = count } | ||
|
|
||
| private var _cellPadding: CGFloat = 0 {didSet { invalidateLayout() }} | ||
| public func setCellPadding(_ padding: CGFloat = 0) { _cellPadding = padding } | ||
|
|
||
| private var cache: [UICollectionViewLayoutAttributes] = [] | ||
|
|
||
| private var _baseItemWidth: CGFloat? { didSet { invalidateLayout() }} | ||
| public func setBaseItemWidth(_ width: CGFloat) { _baseItemWidth = width } | ||
|
|
||
| public var setWidthForColumn: Int? | ||
| public var widthForColumn: ((Int) -> CGFloat?)? = { _ in return nil } | ||
|
|
||
| private var contentHeight: CGFloat = 0.0 | ||
| private var contentWidth: CGFloat { | ||
| guard let collectionView = collectionView else { | ||
| return 0 | ||
| } | ||
| let insets = collectionView.contentInset | ||
| return collectionView.bounds.width - (insets.left + insets.right) | ||
| } | ||
|
|
||
| private var _contentSize: CGSize? { didSet { invalidateLayout() }} | ||
| public func setContentSize(_ size: CGSize) { _contentSize = size } | ||
|
|
||
| private var itemCount: Int { calculateItemCount() } | ||
|
|
||
| open var heightForCellAtIndexPath: ((UICollectionView, IndexPath) -> CGFloat)? | ||
|
|
||
|
|
||
| open func setContentSizeFromCache() { | ||
| if let last = cache.last { | ||
| _contentSize = CGSize(width: contentWidth, height: last.frame.minY + last.frame.height) | ||
| } | ||
| } | ||
|
|
||
| public override var collectionViewContentSize: CGSize { | ||
| return _contentSize ?? CGSize(width: contentWidth, height: contentHeight) | ||
| } | ||
|
|
||
| open func calculateItemCount() -> Int { | ||
| var count = 0 | ||
| if let cv = collectionView { | ||
| for i in 0..<cv.numberOfSections { count += cv.numberOfItems(inSection: i) } | ||
| } | ||
| return count | ||
| } | ||
|
|
||
| public override func prepare() { | ||
| super.prepare() | ||
|
|
||
| cacheFramesAndCalculate() | ||
| setContentSizeFromCache() | ||
|
|
||
| } | ||
|
|
||
| private func calculateXOffset() -> [CGFloat] { | ||
| var columnCount: Int = 0 | ||
| var xOffSet: [CGFloat] = [] | ||
| var offSet: CGFloat = 0 | ||
|
|
||
| if let columnCount = _columnCount { | ||
| if let width = widthForColumn { | ||
| xOffSet = [0] | ||
| let columnWidth = contentWidth / CGFloat(columnCount) | ||
| offSet = columnWidth | ||
| for column in 0..<columnCount - 1 { | ||
| let columnWidth = width(setWidthForColumn!) ?? offSet | ||
| xOffSet.append(columnWidth * CGFloat(column)) | ||
| } | ||
| } else { | ||
| let columnWidth = contentWidth / CGFloat(columnCount) | ||
| offSet = columnWidth | ||
| for column in 0..<columnCount { | ||
| xOffSet.append(offSet * CGFloat(column)) | ||
| } | ||
| } | ||
| } else if let baseWidth = _baseItemWidth { | ||
| if _columnCount == nil { | ||
| columnCount = Int(contentWidth / baseWidth) | ||
| offSet = baseWidth / CGFloat(columnCount) | ||
|
|
||
| for column in 0..<columnCount { | ||
| xOffSet.append(offSet * CGFloat(column)) | ||
| } | ||
| } else { | ||
| columnCount = _columnCount! | ||
| for column in 0..<columnCount { | ||
| xOffSet.append((CGFloat(baseWidth)) * CGFloat(column)) | ||
| } | ||
| } | ||
| } else { | ||
| for column in 0..<2 { | ||
| xOffSet.append((contentWidth / 2) * CGFloat(column)) | ||
| } | ||
| } | ||
| return xOffSet | ||
| } | ||
|
|
||
| open func cacheFramesAndCalculate() { | ||
| cache.removeAll() | ||
| guard cache.isEmpty, let collectionView = collectionView else { return } | ||
|
|
||
| let xOffset = calculateXOffset() | ||
| let columnWidth = contentWidth / CGFloat(_columnCount!) | ||
| var column = 0 | ||
| var yOffset: [CGFloat] = .init(repeating: 0, count: _columnCount!) | ||
|
|
||
| for item in 0..<itemCount { | ||
| let indexPath = IndexPath(item: item, section: 0) | ||
Senbazuru1075 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| let photoHeight = heightForCellAtIndexPath?(collectionView, indexPath) ?? 180 | ||
| let height = _cellPadding * 2 + photoHeight | ||
|
|
||
| //had to give a magic number. Not sure if the magic number is good. | ||
| let frame = CGRect(x: xOffset[column], | ||
| y: yOffset[column], | ||
| width: columnWidth, | ||
| height: height) | ||
| let insetFrame = frame.insetBy(dx: _cellPadding, dy: _cellPadding) | ||
|
|
||
| let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) | ||
| attributes.frame = insetFrame | ||
| cache.append(attributes) | ||
|
|
||
| contentHeight = max(contentHeight, frame.maxY) | ||
| yOffset[column] = yOffset[column] + height | ||
|
|
||
Senbazuru1075 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| column = column < ( _columnCount! - 1) ? (column + 1) : 0 | ||
| } | ||
Senbazuru1075 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { | ||
| var attributes: [UICollectionViewLayoutAttributes] = [] | ||
| for attribute in cache { | ||
| if attribute.frame.intersects(rect) { | ||
| attributes.append(attribute) | ||
| } | ||
| } | ||
| return attributes | ||
| } | ||
|
|
||
| public override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { | ||
| return cache[indexPath.item] | ||
| } | ||
|
|
||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.