我正在尝试UICollectionView
在 iOS 6 中实现无限的水平和垂直滚动。我已经设法让它工作,但它很慢而且不稳定。
StackOverflow 上也有类似的问题,但其中最深入的问题是遵循 Apple 的 WDC 视频并使用集合而不是滚动来实现。我的设计基于这个和类似问题中的其他评论,但仍然无法让它看起来很流畅。
我基本上是在尝试模仿 HBO GO iPad 应用程序的行为,它显示了一个节目网格,并允许您向任何方向滚动它们,当您到达终点时,它只会将节目包裹起来,让您感觉自己在无限滚动.
我所做的是创建一个自定义布局,将单元格排列UICollectionView
在网格中。然后我继承了一个UICollectionView
重写它的layoutSubviews
方法并创建了一个reecenterIfNecessary
函数,就像 Eliza 的 WDC 视频节目一样。这行得通,我得到了无限的“滚动”,但内容没有改变。
所以我创建了一个指向视图控制器的委托,每当它包装时,我告诉委托移动它的数据源,它确实如此,但它没有反映在 中UICollectionView
,所以最后一次调用[self reloadData]
刷新视图,一切都“正常” ”。我得到无限滚动。
但是因为我打电话reloadData
,延迟很明显,滚动条闪烁(从“内容”被“重新加载”)。这是不可接受的,我不知道如何解决它!
任何帮助表示赞赏。我包含了recenterIfNecessary 函数以防万一。
- (void) recenterIfNecessary{
CGPoint currentOffset = [self contentOffset];
CGFloat contentHeight = [self contentSize].height;
CGFloat contentWidth = [self contentSize].width;
//calc center point which would leave same amount of content on both sides
CGFloat centerY = (contentHeight - [self bounds].size.height) / 2.0;
CGFloat centerX = (contentWidth - [self bounds].size.width) / 2.0;
if (currentOffset.x == 0 && currentOffset.y == 0){
//assume this is first load. Set offset to content center.
self.contentOffset = CGPointMake(centerX, centerY);
return;
}
//distance from center is abs of where we are and where we want to be:
CGFloat offsetY = centerY-currentOffset.y;
CGFloat offsetX = centerX-currentOffset.x;
//now we decide if we want to recenter
int deltaX = 0;
int deltaY = 0;
if (fabs(offsetX) > CELL_WIDTH){
if (offsetX < 0){
deltaX = -ceil(offsetX / CELL_WIDTH);
}else{
deltaX = -floor(offsetX / CELL_WIDTH);
}
offsetX += offsetX + (CELL_WIDTH * deltaX);
self.contentOffset = CGPointMake(centerX, currentOffset.y);
}
if (fabs(offsetY) > CELL_HEIGHT){
if (offsetY < 0){
deltaY = -ceil(offsetY / CELL_HEIGHT);
}else{
deltaY = -floor(offsetY / CELL_HEIGHT);
}
offsetY += offsetY + (CELL_HEIGHT * deltaY);
self.contentOffset = CGPointMake(currentOffset.x, centerY);
}
if (fabs(offsetX) > CELL_WIDTH || fabs(offsetY) > CELL_HEIGHT){
//move subviews to reflect scrolling
for (UIView *subview in self.subviews) {
CGPoint center = subview.center;
center.x += offsetX;
center.y += offsetY;
subview.center = center;
}
if ([self.infiniteDataModelDelegate conformsToProtocol:@protocol(InfiniteDataModelProtocol)]){
//moves the data model to reflect "scrolling"
[self.infiniteDataModelDelegate contentDidChangeModelDeltaX:deltaX deltaY:deltaY];
}
[self reloadData];
}
}