Gui*_*rme 22 ios uicollectionview
我有一个可以一次显示大约3.5个单元格的Collection View,我希望它能够启用分页.但我希望它能够捕捉到每个单元格(就像App Store应用程序一样),而不是滚动视图的整个宽度.我怎样才能做到这一点?
Mik*_*e M 51
另一种方法是创建自定义UICollectionViewFlowLayout并覆盖方法,如下所示:
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)offset
withScrollingVelocity:(CGPoint)velocity {
CGRect cvBounds = self.collectionView.bounds;
CGFloat halfWidth = cvBounds.size.width * 0.5f;
CGFloat proposedContentOffsetCenterX = offset.x + halfWidth;
NSArray* attributesArray = [self layoutAttributesForElementsInRect:cvBounds];
UICollectionViewLayoutAttributes* candidateAttributes;
for (UICollectionViewLayoutAttributes* attributes in attributesArray) {
// == Skip comparison with non-cell items (headers and footers) == //
if (attributes.representedElementCategory !=
UICollectionElementCategoryCell) {
continue;
}
// == First time in the loop == //
if(!candidateAttributes) {
candidateAttributes = attributes;
continue;
}
if (fabsf(attributes.center.x - proposedContentOffsetCenterX) <
fabsf(candidateAttributes.center.x - proposedContentOffsetCenterX)) {
candidateAttributes = attributes;
}
}
return CGPointMake(candidateAttributes.center.x - halfWidth, offset.y);
}
Run Code Online (Sandbox Code Playgroud)
https://gist.github.com/mmick66/9812223
如果您正在寻找Swift解决方案,我还创建了一个包含代码的小教程.
Jes*_*sak 17
您可以通过作为集合视图的委托并实现该方法来捕捉单元格:
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
Run Code Online (Sandbox Code Playgroud)
这告诉您用户已完成拖动,并允许您修改targetContentOffset以与您的单元格对齐(即舍入到最近的单元格).请注意,您需要注意如何修改targetContentOffset; 特别是,你需要避免更改它,以便视图需要在传递速度的相反方向滚动,否则你会得到动画故障.如果你谷歌的方法名称,你可以找到很多这方面的例子.
Jon*_*iVR 13
这是我在Swift 5中针对基于单元格的垂直分页的实现:
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
guard let collectionView = self.collectionView else {
let latestOffset = super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)
return latestOffset
}
// Page height used for estimating and calculating paging.
let pageHeight = self.itemSize.height + self.minimumLineSpacing
// Make an estimation of the current page position.
let approximatePage = collectionView.contentOffset.y/pageHeight
// Determine the current page based on velocity.
let currentPage = velocity.y == 0 ? round(approximatePage) : (velocity.y < 0.0 ? floor(approximatePage) : ceil(approximatePage))
// Create custom flickVelocity.
let flickVelocity = velocity.y * 0.3
// Check how many pages the user flicked, if <= 1 then flickedPages should return 0.
let flickedPages = (abs(round(flickVelocity)) <= 1) ? 0 : round(flickVelocity)
let newVerticalOffset = ((currentPage + flickedPages) * pageHeight) - collectionView.contentInset.top
return CGPoint(x: proposedContentOffset.x, y: newVerticalOffset)
}
Run Code Online (Sandbox Code Playgroud)
一些注意事项:
itemSize无法解决问题,请检查您的尺寸是否与项目大小实际匹配,因为这通常是一个问题,尤其是在使用时collectionView(_:layout:sizeForItemAt:),请使用自定义变量来代替itemSize。self.collectionView.decelerationRate = UIScrollView.DecelerationRate.fast。这是水平版本(尚未进行全面测试,因此请原谅任何错误):
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
guard let collectionView = self.collectionView else {
let latestOffset = super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)
return latestOffset
}
// Page width used for estimating and calculating paging.
let pageWidth = self.itemSize.width + self.minimumInteritemSpacing
// Make an estimation of the current page position.
let approximatePage = collectionView.contentOffset.x/pageWidth
// Determine the current page based on velocity.
let currentPage = velocity.x == 0 ? round(approximatePage) : (velocity.x < 0.0 ? floor(approximatePage) : ceil(approximatePage))
// Create custom flickVelocity.
let flickVelocity = velocity.x * 0.3
// Check how many pages the user flicked, if <= 1 then flickedPages should return 0.
let flickedPages = (abs(round(flickVelocity)) <= 1) ? 0 : round(flickVelocity)
// Calculate newHorizontalOffset.
let newHorizontalOffset = ((currentPage + flickedPages) * pageWidth) - collectionView.contentInset.left
return CGPoint(x: newHorizontalOffset, y: proposedContentOffset.y)
}
Run Code Online (Sandbox Code Playgroud)
这段代码基于我在个人项目中使用的代码,您可以在此处下载并运行Example目标,以检出该代码。
| 归档时间: |
|
| 查看次数: |
32174 次 |
| 最近记录: |