-
-
Notifications
You must be signed in to change notification settings - Fork 32
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
Support for more than one item in the cross-axis #38
Comments
Thanks @gcox for raising this issue! That's a good idea to implement. However, it's a bit challenging implement as we need to take into account inter-item/cell spacing and size for items. Also, calculation of current index and scrolling to items at specific indices will change. |
@MaherKSantina Here's the basic implementation details. It is not thoroughly tested and I'm sure I'm missing some edge cases, just want to see if you had any other thoughts on this. I can submit a PR later this week if you don't see any glaring issues here. fileprivate lazy var itemCrossLength: (UIView) -> CGFloat = {
var length: CGFloat = self.scrollDirection.crossLength(for: $0)
let allItemsLength = (length
- (CGFloat(self.numberOfItemsToShowInCrossAxis + 1) * (self.cellSpacing))
- 2)
let finalLength = allItemsLength / CGFloat(self.numberOfItemsToShowInCrossAxis)
return max(0, finalLength)
}
open func scrollView(_ scrollView: UIScrollView, indexForItemAtContentOffset contentOffset: CGPoint) -> Int {
let mainAxisItemLength = itemLength(scrollView) + cellSpacing
guard mainAxisItemLength > 0 else {
return 0
}
let mainAxisOffset = self.scrollDirection.value(for: contentOffset)
guard numberOfItemsToShowInCrossAxis > 1 else {
return Int(round(mainAxisOffset / mainAxisItemLength))
}
let crossAxisItemLength = itemCrossLength(scrollView) + cellSpacing
let crossAxisOffset = self.scrollDirection.crossValue(for: contentOffset)
let minimumIndex = Int(round(mainAxisOffset / mainAxisItemLength)) * numberOfItemsToShowInCrossAxis
let index = minimumIndex + Int(round(crossAxisOffset/crossAxisItemLength))
return index
}
open func scrollView(_ scrollView: UIScrollView, contentOffsetForItemAtIndex index: Int) -> CGFloat {
return CGFloat(index / numberOfItemsToShowInCrossAxis) * (itemLength(scrollView) + cellSpacing)
}
// Assumes we want the full height taken up by equally sized items
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
var defaultSize = collectionView.frame.size
if numberOfItemsToShowInCrossAxis > 1 {
let crossAxisItems = CGFloat(numberOfItemsToShowInCrossAxis)
let crossAxisGapTotal = (crossAxisItems - 1) * cellSpacing
switch scrollDirection {
case .horizontal:
defaultSize.height = (defaultSize.height - crossAxisGapTotal) / crossAxisItems
case .vertical:
defaultSize.width = (defaultSize.width - crossAxisGapTotal) / crossAxisItems
}
}
return scrollDirection.size(for: itemLength(collectionView), defaultSize: defaultSize)
}
public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
...
// Only line that needs to change in this function
let numberOfItemsToScroll = getNumberOfItemsToScroll(scrollDistance: currentScrollDistance, scrollWidth: itemLength(scrollView)) *
numberOfItemsToShowInCrossAxis
...
} That code depends on a couple of new extension methods on |
Ohh @gcox thank you for the code snippet! I'll definitely take a look at it in the weekend |
this is actually supported? |
@Sk8er22 sadly it's not implemented yet. I was focusing on other features that I thought were more important. I deprioritized this one because you can achieve the same behavior by creating a collection view cell that has 3 items. I'm thinking about the complexity this feature adds to the library and it feels like there are a lot of things to take into consideration so I'm still hesitant about it. Do you think you can achieve the same behavior by creating a collection view cell with a vertical stack view and add the views in it? |
I did it doing a custom big cell that contains all the possible stacks. Thanks anyway! |
@Sk8er22 sounds great! I'll add a help-wanted tag in the meantime Have a great day! |
Currently, this lib forces the cross axis size of a cell to match that of the collection view. The App Store has another type of horizontally peeking collection view where multiple cells are displayed vertically in each page. The lib could allow specifying the number of cross-axis items to show, then use that value to calculate the appropriate item size in the
collectionView:layout:sizeForItemAt:
delegate func.Screenshot of the UI I'm referring to
The text was updated successfully, but these errors were encountered: