问题:作为 UIScrollView 的子类的 UICollectionView 基本上以 bounds.size 的步幅对其边界进行动画处理。尽管这可能意味着您所要做的就是在保持框架更大的同时减小边界,但不幸的是 UICollectionView 不会呈现超出其当前边界的任何单元格...破坏您的预览效果。
解决方案:
- 创建一个 UICollectionView,将分页设置为 NO 并使用所需的帧。
- 创建小于 UICollectionView 的框架/边界的 UICollectionViewCells。在这个阶段,下一个单元格的一部分应该显示在框架中。在执行以下其他步骤之前,这应该是可见的。
- 添加一个 collectionView.contentInset.left 和 right (我假设你的布局是水平的)等于 contentOffsetValue 方法(为简单起见如下所示),以便将第一个和最后一个单元格对齐到中间。
- 创建一个 UICollectionViewFlowLayout 覆盖提供停止点的方法,如下所示:
像这样:
-(CGFloat)contentOffsetValue
{
return self.collectionView.bounds.size.width * 0.5f - self.itemSize.width * 0.5f;
}
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
static float EscapeVelocity = 0.5f; // otherwise snap back to the middle
NSArray* layoutAttributesArray = [self layoutAttributesForElementsInRect:self.collectionView.bounds];
if(layoutAttributesArray.count == 0)
return proposedContentOffset;
CGFloat currentBoundsCenterX = self.collectionView.contentOffset.x + self.collectionView.bounds.size.width * 0.5f;
UICollectionViewLayoutAttributes* candidateNextLayoutAttributes = layoutAttributesArray.firstObject;
for (UICollectionViewLayoutAttributes* layoutAttributes in layoutAttributesArray)
{
if ((layoutAttributes.representedElementCategory != UICollectionElementCategoryCell) ||
(layoutAttributes == candidateNextLayoutAttributes)) // skip the first comparison
continue;
if(velocity.x > EscapeVelocity || velocity.x < -(EscapeVelocity))
{
if(velocity.x > EscapeVelocity && layoutAttributes.center.x > candidateNextLayoutAttributes.center.x)
{
candidateNextLayoutAttributes = layoutAttributes;
}
else if (velocity.x < -(EscapeVelocity) && layoutAttributes.center.x < candidateNextLayoutAttributes.center.x)
{
candidateNextLayoutAttributes = layoutAttributes;
}
}
else
{
if(fabsf(currentBoundsCenterX - layoutAttributes.center.x) < fabsf(currentBoundsCenterX - candidateNextLayoutAttributes.center.x))
{
candidateNextLayoutAttributes = layoutAttributes;
}
}
}
return CGPointMake(candidateNextLayoutAttributes.center.x - self.collectionView.bounds.size.width * 0.5f, proposedContentOffset.y);
}