【问题标题】:How to expand UICollectionView contentSize when paging enable?启用分页时如何扩展 UICollectionView contentSize?
【发布时间】:2013-01-28 21:47:08
【问题描述】:

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

如何扩展UICollectionViewcontentSize,使最后一页不包含前一页的任何单元格?

here 为例:UICollectionView 水平滚动 6 个单元格,这样:

  • 第 1 页:

    cell0 - cell1 - cell2 - cell3

  • 第 2 页:

    cell4 - cell5 在意料之中,但出乎意料

    cell2 - cell3 - cell4 - cell5

怎么改?

总结:

我要设置

collectionView.contentSize = numberOfPage * collectionView.frame

不是

collectionView.contentSize = numberOfCell * (cellFrame + spacing)

【问题讨论】:

  • 实际上不应该发生。如果有的话,你能发布代码sn-p吗?
  • 我尝试:[colletonView setContentSize] in viewDidLoad 和 viewDidAppear 但它不起作用,因为 contentSize 将在数据源中被重写。

标签: ios uiscrollview uicollectionview


【解决方案1】:

您可以使用viewDidLayoutSubviews: 方法调整内容。当collection view和所有cell都放在view时调用这个方法,这样你就可以调整cell了。

【讨论】:

  • 不行,滚动时也会调用cellForItemAtIndexPath。
【解决方案2】:

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

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

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

然后在 -collectionView:numberOfItemsInSection: 中撒谎:

    return self.numberOfItemsPerPage * self.numberOfPages;

你当然会拥有比内容更多的单元格,对吧?所以在 -collectionView:cellForItemAtIndexPath: 中只为额外的单元格返回 nil:

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

你去:完整的、可滚动的最后一页。在我看来,水平滚动模式应该只是默认的。

【讨论】:

  • 很确定一个单元格不能为 nil :( 我试过这个并得到这个错误:*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'the collection view's data source did not return a valid cell from -collectionView:cellForItemAtIndexPath: for index path <NSIndexPath: 0xc0000000001a0016>
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    用于水平分页

    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);
    }
    

    【讨论】:

      【解决方案5】:

      您需要继承UICollectionViewLayout 并覆盖collectionViewContentSize 方法。我对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);
      }
      

      旁注,当您使用自定义布局时,您将无法在 Interface Builder 中设置某些显示属性。您可以在自定义 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];
      }
      

      【讨论】:

      • 我被告知这种事情可能会导致巨大的内存占用,因为整个集合视图将被“显示”并且单元格的可重用性是不可能的。这是真的吗?
      • UICollectionView 已经是 UIScrollView 的子类,拥有 contentSize 对它来说很自然,我认为您不必担心单元格的可重用性,因为所有单元格根本不可见。
      • collectionView.collectionViewLayout.collectionViewContentSize() 是您所需要的。如果它无效,只需 collectionView.layoutIfNeeded() 在您获取 contentSize 之前。
      • 如何在 Swift 3.0 中设置 collectionViewContentSize
      【解决方案6】:

      我认为您必须继承 UICollectionViewLayout 并创建自定义布局来管理此类问题。

      【讨论】:

        猜你喜欢
        • 2014-08-09
        • 2017-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多