4

我试图在iOS 6的UICollectionView中实现无限的水平和垂直滚动。我已经设法使它工作,但它很慢且波涛汹涌。如何在iOS 6的UICollectionView中实现无限的水平和垂直滚动?

在StackOverflow上也有类似的问题,但其中最深的是遵循Apple的WDC视频并使用集合而不是滚动来实现。我的设计基于这个以及其他类似问题的评论,但仍然无法让它看起来很流畅。

我基本上是试图模仿HBO GO iPad应用程序的行为,它提供了一个节目的网格,并允许您在任何方向上滚动它们,当您到达结尾时它只是将节目包裹起来,让您感觉像你无限滚动。

我所做的是创建一个自定义布局,在网格中排列UICollectionView单元格。然后我再次分类了一个UICollectionView,它覆盖了它的layoutSubviews方法,并创建了一个像Eliza的WDC视频节目一样的reecenterIfNecessary函数。这工作,我得到无限的“滚动”,但内容不会改变。

所以我创建了一个指向视图控制器的委托,并且每当它包装时,我都会告诉委托移动它的数据源,并且它确实会这样做,但它并不反映在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]; 
} 
} 
+0

您是否找到解决方案?我想知道同样的事情。 – 2013-03-21 12:08:49

+0

不,至少没有超出我发布时的内容,这很有效,但速度很慢,有点“不好”。我最终只是使用常规的scrollView,并使其看起来像一个“集合”视图(网格)。它完美的工作,它只是没有一个collectionView这是我的目标! – Jordan 2013-03-21 22:39:47

+0

我有同样的问题,但重点放在'UIScrollView'上。我得到了你正在寻找的答案..使用用户rdelmar的'UICollectionView'。链接:http://stackoverflow.com/a/15553973/406677 – 2013-03-25 15:25:39

回答

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]; 

    } 
} 
1

我已经放在一起提供了一个无限滚动视图在所有方向的库。当用户滚动时,框架会布置图块并让委托人知道,以便可以设置图块的演示。至于性能,该框架没有引入滞后:完整的60 fps。

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