59

发生了什么

目前我有一个UICollectionViewsUITableView. 通过这种方式,我创建了一个看起来像 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;

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


编辑 2.0

我改变了创建单元格的方式,而不是出队,我使用的是旧方式:

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

还是一样的悲惨结果。

4

12 回答 12

38

那么,什么起作用了?

1)子类UICollectionViewFlowLayout

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

3)在UICollectionViewFlowLayout子类的init方法上,设置你想要的方向:

self.scrollDirection = UICollectionViewScrollDirectionHorizontal;

就我而言,它是水平的。

4)重要部分

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

此刻,我应该有点理论,但老实说,我没有头绪。

于 2012-11-13T21:02:32.917 回答
18

上面的答案对我不起作用,但是在下载图像后,我将代码替换 [self.myCollectionView reloadData][self.myCollectionView reloadSections:[NSIndexSet indexSetWithIndex:0]]; 刷新 collectionview 并显示所有单元格,您可以尝试一下。

于 2015-06-26T18:21:27.533 回答
8

任何人提供的解决方案都没有帮助我实现我们需要在我们的应用程序中拥有的自定义布局。相反,我必须这样做:(是的,可以工作!!!)

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

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

于 2015-11-20T10:53:12.250 回答
3

Rob 关于这个错误的提示帮助了我。该错误指出,如果部分插图和单元格的宽度和间距加起来正好等于屏幕的宽度,那么第一列有时会随机消失并在某些地方的某些单元格中重新出现。我没有子类化或更改单元格宽度,而是将故事板中左右的部分插图从 6 更改为 4,但我再也没有看到问题。

于 2013-01-16T03:38:21.040 回答
1

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

当我将估计的高度设为低时,所有单元格都正确显示。

于 2016-09-19T04:02:33.623 回答
1

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

于 2018-01-08T04:47:09.610 回答
1

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

问题的先决条件:

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

问题

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

问题的根源在于UICollectionViewFlowLayout.

正如它在文档中明确指出的那样:

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

- 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子类化。覆盖所有需要覆盖的方法,一切都会正常工作。

于 2018-10-30T13:08:06.137 回答
0

刚刚遇到了一个问题,即所有 UICollectionView 单元格在滚动时都消失了。

发生这种情况是因为我已经宣布

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

...意味着在多个 UICollectionView 中使用了相同的布局实例。我本来打算把它变成一个计算变量。希望这可以帮助那些不小心在多个集合视图中使用相同布局对象的人。

于 2019-11-28T00:05:20.940 回答
0

在我的情况下,导致单元格消失的原因是数据源被过早地释放。UICollectionView.dataSource是一个弱属性,这意味着除非您保持对它的强引用,否则该对象将在您创建的范围结束时被释放。当我点击UICollectionView.

于 2021-03-16T14:17:06.383 回答
-1

对我来说,这个问题似乎与我让我的 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#,但我希望它对其他人有所帮助。

于 2017-08-11T13:21:29.830 回答
-1

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

你可以看到这个演示:https ://github.com/lqcjdx/YLTagsChooser ,所有的单元格都可以在滑动 UICollectionView 时出现。

于 2017-09-08T03:52:52.833 回答
-1

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

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

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

DispatchQueue.main.async {}

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

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

带线的方法

 if let lastScrollView = lastScrollView {}

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

于 2021-03-05T09:24:53.657 回答