UICollectionView的单元格消失了

时间:2012-11-13 12:42:02

标签: ios xcode uicollectionview uicollectionviewcell

发生了什么

目前我的应用程序在UICollectionViews内使用了两个UITableView。这样我创建了一个类似应用程序的Pulse News。我的问题是,有时第6行和第11行完全消失,留下一个空白区域应该是单元格。我真的不介意,如果所有细胞都是这样的(这种方式我可以假设我没有做正确的事情),但问题是,正好发生在那些特定的细胞上。

我的理论

第6行和第11行是我开始滚动时出现的行,所以默认情况下我能看到5个单元格,当我进行第一次水平滚动时,第6行会出现(有时会出现空白)。

我有什么

我现在唯一要做的就是:

 [self.collectionView registerNib:[UINib nibWithNibName:CELL_NIB_NAME bundle:nil] forCellWithReuseIdentifier:CELL_IDENTIFIER];

viewDidLoad上。在创建细胞时:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    MyCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CELL_IDENTIFIER forIndexPath:indexPath];

    NSMutableDictionary *dictionary = [self.DataSource objectAtIndex:[indexPath row]];

    [cell buildViewWithDictionary:dictionary withReferenceParent:self.referenceViewController];

    return cell;
}

所以在我的提示中,没有任何幻想在这里发生。我虽然在数据源(虚拟JSON文件)上有问题,但有时它工作正常并且单元格显示,所以我想从那部分是可以的。

所以我的“问题”:有谁知道发生了什么?我真的不想说这是来自iOS的错误,但我想不出别的什么。


修改1.0

令人惊讶的是这个方法

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;

indexPath [0,4]到[0,6]而不计算[0,5]。我第一次真正在iOS中看到这种情况。


编辑2.0

我已经改变了创建单元格的方式,而不是出列我正在使用旧方法:

NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CELL_NIB_NAME owner:self options:nil];
MyCell *cell = (MyCell *)[nib objectAtIndex:0];

仍然是同样悲伤的结果。

12 个答案:

答案 0 :(得分:34)

那么,做了什么工作?

1)子类UICollectionViewFlowLayout

2)将我的UICollectionView的flowLayout设置为我的新子类。

3)在UICollectionViewFlowLayout子类的init方法中,设置所需的方向:

self.scrollDirection = UICollectionViewScrollDirectionHorizontal;

就我而言,它是水平的。

4)重要部分

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
   return YES;
}

此时此刻,我应该提出一点理论,但说实话,我并不知道。

答案 1 :(得分:14)

上述答案对我不起作用,但在下载图像后,我更换了代码 [self.myCollectionView reloadData][self.myCollectionView reloadSections:[NSIndexSet indexSetWithIndex:0]]; 要刷新集合视图并显示所有单元格,您可以尝试它。

答案 2 :(得分:6)

任何人提供的解决方案都没有帮助我完成我们的应用程序中需要的自定义布局。 相反,我必须这样做:(是的, IT WORKS !!!)

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
    CGSize size = [self collectionViewContentSize];
    rect.size.height = size.height*2;
    NSArray *atrributes_Super = [super layoutAttributesForElementsInRect:rect];
    return atrributes_Super;
}

毕竟,UICollectionView只是寻找要在屏幕矩形中显示的元素的属性。

答案 3 :(得分:3)

Rob的关于这个bug的提示对我有所帮助。该错误表明,如果部分插入并且单元格的宽度和间距与屏幕的宽度完全相加,则第一列有时会随机消失,并在某些地方重新出现。我没有子类化或更改单元格宽度,而是将故事板中左右两侧的部分插入从6更改为4,并且我没有再次看到问题。

答案 4 :(得分:2)

当我突然遇到相同的问题并花了一些时间找出滚动过程中单元消失的可能原因之一时,我也会添加答案。

问题的先决条件:

  1. 您有一个UICollectionView实例
  2. 您有一个UICollectionViewFlowLayoutSubclass

问题

单元格滚动到特定点后将从“集合视图”中消失。

问题的根源是UICollectionViewFlowLayout的错误子类化。

documentation中明确指出:

  

每个布局对象都应实现以下方法:

- collectionViewContentSize
- layoutAttributesForElements(in:)
- layoutAttributesForItem(at:)
- layoutAttributesForSupplementaryView(ofKind:at:) // (if your layout supports -supplementary views)
-layoutAttributesForDecorationView(ofKind:at:) // (if your layout supports decoration views)
- shouldInvalidateLayout(forBoundsChange:)

依靠上述方法的UICollectionViewFlowLayout实现,我们错过了一个事实,即func layoutAttributesForElements(in rect: CGRect)collectionViewContentSize会生成错误的 contentSize (大小正确)

如果所有单元格的大小都为itemSize,并且内容大小也相应,则滚动offsetY越大,高度contentSize的单元格就会全部消失。

解决方案

解决方案是使用正确的UICollectionViewFlowLayout子类。覆盖所有required to override的方法,一切都将正常工作。

答案 5 :(得分:1)

在我的情况下(垂直滚动,细胞在第一个视图中消失),细胞由于估计的大小不正确而消失。似乎UICollectionView使用估计的大小来计算要在第一个视图中加载的项目。我将估计的尺寸设置得太高,导致在第一个屏幕中加载的项目数量计算错误。

当我估计高度位低时,所有细胞都正确显示。

答案 6 :(得分:0)

对我来说,这个问题似乎与我使我的collectionview适应开放式键盘以防止内容重叠的方式有关。

在我的观察者中回应KeyboardWillShow我有这个:

var userInfo = obj.UserInfo[UIKeyboard.FrameEndUserInfoKey];
if (userInfo is NSValue value)
{
    var rect = value.CGRectValue;
    var windowOffset = this.Superview.ConvertPointToView(this.Frame.Location, UIApplication.SharedApplication.KeyWindow);
    var newHeight = rect.Y - windowOffset.Y;

    this._controller.CollectionView.Frame = new CGRect(0, 0, this._controller.CollectionView.Frame.Width, newHeight);
}

将其更改为:

var userInfo = obj.UserInfo[UIKeyboard.FrameBeginUserInfoKey];
if (userInfo is NSValue value)
{
    var rect = value.CGRectValue;
    UIEdgeInsets contentInsets = new UIEdgeInsets(0, 0, rect.Height, 0);
    this._controller.CollectionView.ContentInset = contentInsets;
    this._controller.CollectionView.ScrollIndicatorInsets = contentInsets;
}

细胞消失问题彻底消失了。这是使用xamarin的C#,但我希望它可以帮助其他人。

答案 7 :(得分:0)

我认为这不是UICollectionView的错误,也许你没有用- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect方法返回正确的数据。

你可以看到这个演示:https://github.com/lqcjdx/YLTagsChooser,在收集UICollectionView时可以显示所有单元格。

答案 8 :(得分:0)

我们最近遇到了消失的细胞,发现并没有跳过“隐藏”的细胞。我们不小心插入了0x0大小的单元格。由此产生的行为非常混乱,并没有暗示这些看不见的细胞是问题。我们会看到正确大小的单元格和布局,但是在屏幕上滚动后,一些有效单元格会一直消失。我不知道为什么混合0大小的单元格会导致这种行为,但删除它们解决了这个问题。这可能不会导致您的问题,但这可能有助于开发人员搜索类似的症状。

答案 9 :(得分:0)

碰到一个问题,所有UICollectionView单元都在滚动中消失了。

这是因为我已经宣布

extension UICollectionViewLayout {
    static let defaultLayout: UICollectionViewLayout {
        let layout = UICollectionViewFlowLayout()
        layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
        return layout
    }()
}

...表示在多个UICollectionView中使用了相同的布局实例。我本来想让它成为一个计算变量。希望这对在多个集合视图中意外使用同一布局对象的人有所帮助。

答案 10 :(得分:0)

就我而言,消失的单元格问题是由于 项目中添加了 IQKeyboardManager SDK。 因为这个SDK会在整个项目中触发键盘的动画,即使你不直接将它添加到分离的文件中。

对我来说奇怪的是,只有当您为集合视图添加 UIEdgeInset 时才会出现问题,在我的情况下从 .bottom 开始高于 40。

如何解决?你需要解锁pod文件并添加

DispatchQueue.main.async {}

对于这个动画。 如果 UICollectionViewController 是它的内部

@objc internal func keyboardWillHide(_ notification: Notification?) {}

带线的方法

 if let lastScrollView = lastScrollView {}

当你为此动画添加主队列时,问题消失。

答案 11 :(得分:0)

在我的案例中导致单元格消失的原因是数据源被过早释放。 UICollectionView.dataSource 是一个弱属性,这意味着除非您保持对它的强引用,否则该对象将在您创建的范围的末尾被释放。当我点击 UICollectionView 时,问题就出现了,单元格消失了。