【问题标题】:UICollectionViewFlowLayout's estimatedItemSize breaks scrolling?UICollectionViewFlowLayout 的estimatedItemSize 打断滚动?
【发布时间】:2014-12-26 17:10:24
【问题描述】:

(EDIT :从 iOS 9 开始似乎运行良好。我没有进行广泛的测试,但该示例有效。这证实了 iOS 中存在的错误8.)

我花了很多时间测试 UICollectionView 的 Flow Layout 自调整大小行为。在经历了很多挫折之后,问题被缩小到这样一个事实,即一旦将estimatedItemSize 设置为非零大小,滚动就不再正常工作。

在我的示例中,它只显示 32 个,而不是显示 40 个项目。

我已经复制粘贴了下面的代码。我已经从 Swift 版本开始测试了很多东西。

基本上它无法计算和/或正确更新布局的collectionViewContentSize()

这是一个完整的演示http://git.io/AIrHNA

谁能指出我正确的方向?

谢谢

@implementation ViewControllerObjcC

static NSString * const reuseIdentifier = @"Cell";
-(UICollectionViewFlowLayout*)flowLayout{
  return (UICollectionViewFlowLayout*)self.collectionViewLayout;
}

- (void)viewDidLoad {
  [super viewDidLoad];
  [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
  CGSize estimatedSize = CGSizeMake(self.view.frame.size.width, 25.0);
  BOOL testEstimatedItemSize = true;
  if (testEstimatedItemSize) {
    [self flowLayout].estimatedItemSize = estimatedSize;
  }else{
    [self flowLayout].itemSize = estimatedSize;
  }

}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return 40;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
  UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 30)];
  [cell.contentView addSubview:label];
  label.text = [NSString stringWithFormat:@"%ld",(long)indexPath.row];
  label.backgroundColor = [UIColor redColor];
  return cell;
}

【问题讨论】:

  • 听到您完全可以使用estimatedItemSize,我感到很惊讶。根据我的经验,当我使用它时发生的一切就是我崩溃了。我的结论是,尽管在 WWDC 2014 视频中宣传了这种自定尺寸单元的功能,但从未真正上线。所以我的建议是:不要尝试使用此功能,只需像我们在 iOS 7 中那样“手动”测量项目大小,就可以了。 (当然我很高兴得知我错了,它已经开始起作用了......)
  • 马特,感谢您的宝贵意见。在写第一篇文章时,我在想你在告诉我什么。无论如何,花这么多时间研究这个问题让我很沮丧,在 WWDC 上宣传为已解决。如前所述,我已将问题缩小到一个简单的示例,并且我愿意深入研究它。我希望我遗漏了一些东西,有人会帮我看看。

标签: ios objective-c iphone uicollectionview uicollectionviewlayout


【解决方案1】:

来自Apple's Document

具体来说,不在屏幕上的单元格被假定为估计高度

这是我的猜测。

当估计高度小于实际单元格高度时,集合视图的内容大小预测小于实际内容大小。

因此它只显示总共 40 个单元格中的 32 个。

在我的项目中,使用较大的估计大小时会显示所有 celsl。

【讨论】:

    【解决方案2】:

    来自文档:

    此属性的默认值为CGSizeZero。将其设置为任何 其他值导致集合视图查询每个单元格的 使用单元格的实际大小 preferredLayoutAttributesFittingAttributes: 方法。如果你的所有 单元格高度相同,请使用 itemSize 属性,而不是 这个属性,来指定单元格大小。

    您的项目中似乎没有使用这个preferredLayoutAttributesFittingAttributes:方法?,您是否尝试过实现它?

    另一方面,这个解决方案看起来不错: Specifying one Dimension of Cells in UICollectionView using Auto Layout

    【讨论】:

      【解决方案3】:

      我有同样的问题。在我的例子中,项目之间的空间是 32。我的代码是这样的:

      collectionViewLayout.minimumInteritemSpacing = 0
      collectionViewLayout.minimumLineSpacing = 32
      collectionViewLayout.scrollDirection = .horizontal
      collectionViewLayout.itemSize = UICollectionViewFlowLayout.automaticSize
      collectionViewLayout.estimatedItemSize = CGSize(width: 100, height: 32)
      

      我将minimumInteritemSpacing 更改为与minimumLineSpacing 相同的32 以解决问题。

      collectionViewLayout.minimumInteritemSpacing = 32
      

      【讨论】:

        猜你喜欢
        • 2021-03-01
        • 1970-01-01
        • 2018-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多