我正在使用UICollectionView,使得集合视图单元格位于屏幕的中心,左右单元格部分可见。 Infect,UICollectionView宽度等于屏幕宽度,单元格宽度较小,因此左右单元格应该部分可见。 为了实现分页,我实现了自定义代码,将中心单元设置在屏幕的中心。现在它创造了一些问题;我希望得到任何默认方法来避免导致问题的自定义实现。
我想以这样的方式启用分页,以便在下面的图像中实现所描述的行为。
如果我禁用自定义实现并启用默认分页,则会部分显示两个单元格,但它不是我想要的预期行为。
由于
答案 0 :(得分:2)
据我所知,您无法通过"默认"来执行此操作,您需要自定义您的collectionView。我实现这一点的方法是通过继承collectionView的流布局并实现以下方法:
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
CGFloat offSetAdjustment = MAXFLOAT;
CGFloat horizontalCenter = (CGFloat) (proposedContentOffset.x + (self.collectionView.bounds.size.width / 2.0));
CGRect targetRect = CGRectMake(proposedContentOffset.x, 0.0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
NSArray *array = [self layoutAttributesForElementsInRect:targetRect];
UICollectionViewLayoutAttributes *currentAttributes;
for (UICollectionViewLayoutAttributes *layoutAttributes in array)
{
if(layoutAttributes.representedElementCategory == UICollectionElementCategoryCell)
{
CGFloat itemHorizontalCenter = layoutAttributes.center.x;
if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offSetAdjustment))
{
currentAttributes = layoutAttributes;
offSetAdjustment = itemHorizontalCenter - horizontalCenter;
}
}
}
CGFloat nextOffset = proposedContentOffset.x + offSetAdjustment;
proposedContentOffset.x = nextOffset;
CGFloat deltaX = proposedContentOffset.x - self.collectionView.contentOffset.x;
CGFloat velX = velocity.x;
// detection form gist.github.com/rkeniger/7687301
// based on http://stackoverflow.com/a/14291208/740949
if(deltaX == 0.0 || velX == 0 || (velX > 0.0 && deltaX > 0.0) || (velX < 0.0 && deltaX < 0.0)) {
} else if(velocity.x > 0.0) {
for (UICollectionViewLayoutAttributes *layoutAttributes in array)
{
if(layoutAttributes.representedElementCategory == UICollectionElementCategoryCell)
{
CGFloat itemHorizontalCenter = layoutAttributes.center.x;
if (itemHorizontalCenter > proposedContentOffset.x) {
proposedContentOffset.x = nextOffset + (currentAttributes.frame.size.width / 2) + (layoutAttributes.frame.size.width / 2);
break;
}
}
}
} else if(velocity.x < 0.0) {
for (UICollectionViewLayoutAttributes *layoutAttributes in array)
{
if(layoutAttributes.representedElementCategory == UICollectionElementCategoryCell)
{
CGFloat itemHorizontalCenter = layoutAttributes.center.x;
if (itemHorizontalCenter > proposedContentOffset.x) {
proposedContentOffset.x = nextOffset - ((currentAttributes.frame.size.width / 2) + (layoutAttributes.frame.size.width / 2));
break;
}
}
}
}
proposedContentOffset.y = 0.0;
return proposedContentOffset;
}
(这段代码很大程度上来自我在SO上找到的其他内容,但我现在无法找到参考资料。)
在我的情况下,集合视图没有被分页,但是这个方法使它的行为像它一样。
此外,如果要使集合视图的第一个单元格从屏幕中心开始(对于最后一个单元格相同),则必须在UICollectionViewDelegateFlowLayout
中重写此方法
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
CGFloat leftInset = (self.view.bounds.size.width - CELL_WIDTH) / 2; // CELL_WIDTH is the width of your cell
return UIEdgeInsetsMake(0, leftInset, 0, leftInset);
}
此方法假定collectionView与屏幕一样宽。如果您不是这种情况,请通过计算collectionView的左右插图来使其适应您的需求。