4

我正在尝试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];
}
}
4

2 回答 2

1

我已经建立了一个库,可以在各个方向提供无限滚动的视图。当用户滚动时,框架会布置图块并让代理知道,以便它可以设置图块的演示文稿。至于性能,该框架没有引入延迟:全 60 fps。

带有在无限滚动墙上显示 Flickr 图像的示例应用程序的框架在这​​里:https ://github.com/vovagalchenko/scroll-for-days 。此外,这里是示例应用程序的视频:https ://cloud.box.com/s/d6bgvlot175au5a3jeh5

于 2014-03-10T02:16:31.423 回答
0

你试过这种方法吗?

-(void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{
    if ([self.products count] > 8 && indexPath.row == [self.products count] - 8) {
        [self loadMoreItems];
        [self.collectionView reloadData];

    }
}
于 2013-09-07T22:21:42.943 回答