ios UICollectionView 的单元格消失

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13360975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:11:47  来源:igfitidea点击:

UICollectionView's cell disappearing

iosxcodeuicollectionviewuicollectionviewcell

提问by Rui Peres

What's happening

发生了什么

Currently I have an application that uses two UICollectionViewsinside a UITableView. This way I create a Pulse News look like application. My problem with this is that sometimes the 6th and 11th row disappears completely, leaving a blank space where it should be the cell. I wouldn't actually mind, if all the cells were like this (and this way I could assume that I wasn't doing things correctly), but the thing is, is just happening with those specific ones.

目前我有一个应用程序UICollectionViewsUITableView. 通过这种方式,我创建了一个看起来像 Pulse News 的应用程序。我的问题是有时第 6 行和第 11 行完全消失,在它应该是单元格的地方留下一个空白区域。我实际上并不介意,如果所有的细胞都是这样(这样我就可以假设我没有正确地做事),但事情是,只是发生在那些特定的细胞上。

My theory

我的理论

The 6th and 11th rows are the ones that appears when I start scrolling, so by default I am able to see 5 cells, and when I do the first horizontal scrolling the 6th comes up (blank space sometimes).

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

What I have

我拥有的

The only thing I am doing at the moment is this:

我目前唯一在做的事情是:

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

On the viewDidLoad. And on the creation of the cell:

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

So on my understating nothing fancy going on here. I though there was something wrong on the data source (a dummy JSON file), but sometimes it works ok and the cell shows, so I guess from that part is ok.

所以在我的理解中,这里没有什么花哨的事情。我虽然数据源(一个虚拟的 JSON 文件)有问题,但有时它工作正常并且单元格显示,所以我猜从那部分是可以的。

So my "question": Does anyone knows what's going on? I don't really like to say that it's a bug from iOS, but I can't think of anything else.

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



Edit 1.0

编辑 1.0

The amazing part is that this method

令人惊奇的是,这种方法

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

Is going from indexPath[0,4] to [0,6] without calculating the [0,5]. First time I actually see this happening in iOS.

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



Edit 2.0

编辑 2.0

I have switched the way I am creating the cells, and instead of dequeuing I am using the old way:

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

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

Still the same sad result.

结果还是一样的悲惨。

采纳答案by Rui Peres

So, what did work?

那么,什么起作用了?

1) Subclass UICollectionViewFlowLayout.

1) 子类UICollectionViewFlowLayout

2) Set the flowLayout of my UICollectionViewto my new subclass.

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

3) On the init method of the UICollectionViewFlowLayoutsubclass, set the orientation you want:

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

self.scrollDirection = UICollectionViewScrollDirectionHorizontal;

In my case it is Horizontal.

在我的情况下,它是水平的。

4) The important part:

4)重要部分

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

At this moment, I should theorise a bit, but honestly I don't have a clue.

此刻,我应该稍微推理一下,但老实说我没有任何头绪。

回答by Yao Li

The above answers didn't work for me, but after downloading the images, I replaced the code [self.myCollectionView reloadData]with [self.myCollectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];to refresh the collectionview and it shows all cells, you can try it.

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

回答by Saru

None of the solutions given by anyone helped me in my custom layout that we need to have in our app. Instead, I had to do this: (And yeah, 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;
}

After all, UICollectionView is just looking for the attributes for the elements to be displayed in your screen's rect.

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

回答by hoak

Rob's tip about the bug helped me. The bug states that if the section insets and cells widths and spacing add up exactly to the width of the screen then the first column sometimes randomly dissappears and reappears for some cells in some places. Rather than subclass or change the cell widths, I changed the section insets for left and right in my storyboard from 6 to 4 and it I haven't seen the problem again.

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

回答by fewlinesofcode

As I run the same problem suddenly and spent some time figuring out one of possible reasons of cell disappearing during the scroll, I will add my answer as well.

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

Prerequisites of the problem:

问题的先决条件:

  1. You have a UICollectionViewinstance
  2. You have a UICollectionViewFlowLayoutSubclass
  1. 你有一个UICollectionView实例
  2. 你有一个 UICollectionViewFlowLayoutSubclass

The problem

问题

Cells disappear from the Collection View after scrolling to the certain point.

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

The source of the problem is in wrong subclassing of the UICollectionViewFlowLayout.

问题的根源在于UICollectionViewFlowLayout.

As it explicitly said in documentation:

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

Every layout object should implement the following methods:

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

- 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:)

By relying on UICollectionViewFlowLayoutimplementation of methods above we miss the fact, that func layoutAttributesForElements(in rect: CGRect)and collectionViewContentSizewill generate wrong contentSize(the size that would be correct if all the cells would have itemSizesize and the content size would be corresponding. As soon as scroll offsetYwill be greater that contentSizeheight cell will all disappear.

依靠UICollectionViewFlowLayout实施以上方法,我们错过了事实,func layoutAttributesForElements(in rect: CGRect)collectionViewContentSize会产生错误的contentSize(大小,这将是正确的,如果所有的细胞将有itemSize大小,并会相应内容大小,一旦滚动offsetY将大于contentSize高度单元都会消失。

The solution

解决方案

The solution is in proper UICollectionViewFlowLayoutsubclassing. Override all the methods that are required to overrideand everything will work just fine.

解决方案是适当的UICollectionViewFlowLayout子类化。覆盖所有需要覆盖的方法,一切都会正常工作。

回答by chandan thakur

In my case (vertical scroll, with cells disappearing in first view), cells were disappearing due to incorrect estimated size. It seems, UICollectionViewuses the estimated size to calculate the items to load in first view. I'd set the estimated size too high which was resulting in wrong calculations for number of items to load in first screen.

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

The moment I made the estimated height bit low, all the cells appeared correctly.

我把估计的高度调低的那一刻,所有的细胞都正确出现了。

回答by tyler

We ran into disappearing cells recently and found that rather than skipping 'hidden' cells we were accidentally inserting 0x0 sized cells. The resulting behavior was very confusing and did not suggest these invisible cells were the issue. We would see the correctly sized cells and layout, but a few of the valid cells would consistently disappear after scrolling off/on screen. I have no idea why intermingling 0 sized cells would cause this behavior, but removing them fixed the problem. This may not be causing your problem, but this may be helpful to devs searching for similar symptoms.

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

回答by Dbl

For me this issue seemed to be related with the way i make my collectionview adapt to an open keyboard to prevent content overlaps.

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

in my observer to respond to KeyboardWillShow i had this:

在我的观察者回应 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);
}

After changing it to this:

改成这样后:

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

The cell disappearance issue completely went away. This is C# from working with xamarin but i hope it helps someone else.

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

回答by lambert.lu

I think this is not a UICollectionView‘s bug, maybe your not return right data in - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rectmethod.

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

You can see this demo: https://github.com/lqcjdx/YLTagsChooser, all cells can appear when scolling the UICollectionView.

可以看到这个demo:https: //github.com/lqcjdx/YLTagsChooser,滚动UICollectionView时可以出现所有单元格。

回答by Peter

Just ran into an issue where all UICollectionView cells were disappearing on scroll.

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

This happened because I had declared

这发生是因为我已经声明

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

... meaning the same layout instance was being used in multiple UICollectionViews. I had meant to make that a computed var. Hope this helps someone who's accidentally using the same layout object in multiple collection views.

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