如何在分页启用时展开UICollectionView contentSize?

问题描述:

我正在做一个简单的UICollectionView启用分页机制,并且一切正常。但是,滚动到最后一页时,单元格的数量在屏幕中并不完全可见,最后一页包含上一页的一些单元格。如何在分页启用时展开UICollectionView contentSize?

如何扩大UICollectionViewcontentSize以便最后一页不包含上一页的任何单元格?

一个例子here

第1页::cell0 - cell1 - cell2 - cell3

滚动:小区2-CELL3-CELL4-cell5 //未预期:如何改变与6个细胞,这样的UICollectionView水平滚动: cell4 - 第2页中的单元格5。

摘要:

我想设置

collectionView.contentSize = numberOfPage * collectionView.frame

collectionView.contentSize = numberOfCell * (cellFrame + spacing)

+0

实际上它不应该发生。如果有的话,你可以写邮政代码片段吗? – Swapnil 2013-02-13 11:43:02

+0

我尝试:viewDidLoad和viewDidAppear中的[collectonView setContentSize]但它不起作用,因为contentSize将在数据源中重写。 – 2013-02-13 11:48:27

您需要继承UICollectionViewLayout并覆盖collectionViewContentSize方法。我subclassed UICollectionViewFlowLayout,所以我不会重新编写所有的布局代码。

我建立一个4x4网格,所以我的方法是这样的:

- (CGSize)collectionViewContentSize 
{  
    NSInteger itemCount = [self.collectionView numberOfItemsInSection:0]; 
    NSInteger pages = ceil(itemCount/16.0); 

    return CGSizeMake(320 * pages, self.collectionView.frame.size.height); 
} 

侧面说明,当您使用自定义的布局,你失去了设置的一些在显示属性的能力界面生成器。您可以在您自定义的UICollectionViewLayout子类的init方法中以编程方式设置它们。下面是我的参考:

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     [self setup]; 
    } 

    return self; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super init]; 
    if (self) { 
     [self setup]; 
    } 

    return self; 
} 

- (void)setup 
{ 
    self.itemSize = CGSizeMake(65.0f, 65.0f); 
    self.minimumLineSpacing = 15; 
    self.sectionInset = UIEdgeInsetsMake(7.5f, 7.5f, 30.0f, 7.5f); 
    [self setScrollDirection:UICollectionViewScrollDirectionHorizontal]; 
} 
+0

我被告知这种事情可能会导致巨大的内存占用,因为整个集合视图将被“显示”,并且细胞的重用性将不可能实现。这是真的? – 2014-07-23 19:08:48

+0

UICollectionView已经是UIScrollView的子类,并且contentSize对它来说很自然,我不认为你必须担心单元重用性,因为所有的单元根本不可见。 – 2015-10-14 13:41:44

+0

'collectionView.collectionViewLayout.collectionViewContentSize()'是你需要的。如果它无效,在获取contentSize之前,只需要'collectionView.layoutIfNeeded()'。 – 2016-03-29 13:47:33

您还可以调节与viewDidLayoutSubviews:米内容ethod。此方法在集合视图和所有单元格放置在view中时调用,以便您可以调整单元格。

+0

它不工作,cellForItemAtIndexPath也滚动时调用。 – 2013-02-13 12:16:07

我认为你必须继承UICollectionViewLayout并创建自定义布局来管理这些类型的问题。

对于水平分页

if(CollectionView.pagingEnabled) 
{ 

    int numberOfPages = floor(collectionView.contentSize.width/
         collectionView.frame.size.width) + 1; 
          CGFloat 
    float requierdWidth=self.collectionView.frame.size.width*numberOfPages; 

    self.Layout.footerReferenceSize=CGSizeMake(requierdWidth-self.collectionView.contentSize.width,0); 
} 

答案的效果很好,但对我们的代码,我们有每页一个部分。所以这意味着我们的布局类的覆盖只是

-(CGSize) collectionViewContentSize { 
    return CGSizeMake(CGRectGetWidth(self.collectionView.frame) * 
       [self.collectionView numberOfSections], 
       CGRectGetHeight(self.collectionView.frame)) ; 
} 

我有一个答案,不需要任何子类化。

在-viewDidLoad中,计算每页有多少项目以及您将拥有多少页面。将这些值存储在属性中。

self.numberOfItemsPerPage = NumberOfRows * NumberOfColumns; 
    self.numberOfPages = ceilf((CGFloat)self.items.count/(CGFloat)self.numberOfItemsPerPage); 

然后在-collectionView:numberOfItemsInSection:只是骗它:

return self.numberOfItemsPerPage * self.numberOfPages; 

当然,你将有更多的细胞比的内容,对不对?因此,在-collectionView:cellForItemAtIndexPath:只返回零的额外电池:

if (indexPath.item > [self.items count] - 1) { 
    //We have no more items, so return nil. This is to trick it to display actual full pages. 
    return nil; 
    } 

你去那里:满,滚动最后一页。在我看来,水平滚动模式应该默认为这个。

+0

很确定一个单元格不能为零:(我试过这个,并得到这个错误:***终止应用程序,由于未捕获的异常'NSInternalInconsistencyException',原因:'集合视图的数据源没有从-collectionView返回有效的单元格:cellForItemAtIndexPath:用于索引路径 taber 2014-07-16 05:22:38