具有动态高度的 UICollectionView 错误 [英] A UICollectionView bug with a dynamic height

查看:22
本文介绍了具有动态高度的 UICollectionView 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于我已经为这个问题苦苦挣扎了 3 天,并且已经问过两次,但可能还不清楚,我决定调查这个问题 &发现此视图存在错误行为.

Since I have been struggling for 3 days with this problem and have asked about it twice already, but maybe was not clear, I had decided to investigate the issue & found a buggy behavior with this view.

我将展示整个简单代码,以便任何人都可以重现该错误(iPad Air).

I will show the entire simple code, so anyone can reproduce the bug (iPad Air).

我正在设置一个 collectionView 流程布局,它对布局进行子类化以获得单元格之间的恒定间距,这是开始:

I am setting a collectionView flowlayout that subclasses the layout to get a constant spacing between cells, and here is the start:

 TopAlignedCollectionViewFlowLayout *layout = [[TopAlignedCollectionViewFlowLayout alloc] init];
 CGRect size = CGRectMake(0, 0, 900, 1200);

 self.GridView = [[UICollectionView alloc] initWithFrame:size
                                    collectionViewLayout:layout];
 [self.GridView registerClass:[GridCell class] forCellWithReuseIdentifier:@"Cell"];
 [self.GridView setDelegate:self];
 [self.GridView setDataSource:self];
 [self.view addSubview:self.GridView];

然后设置我的代表就这么简单:(高度是动态的)

Then setting my delegates is as simple as that : (height is dynamic )

#pragma grid- main functions
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 80;
}

//cell size
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout
                                            sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
{
    //a random dynamic height of a cell 
    int a = arc4random()%300;
    CGSize size = CGSizeMake( 340,  240+a );
    return size;
}

-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView 
                cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier=@"Cell";
    GridCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier 
                                                               forIndexPath:indexPath];
    cell.textL.text=[NSString stringWithFormat:@"%d",indexPath.row];
    NSLog(@"%d",indexPath.row);
    return cell;
}

现在是子类,要获得一个恒定的间距:(TopAlignedCollectionViewFlowLayout)

Now the subclass, to get a constant spacing : (TopAlignedCollectionViewFlowLayout)

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSArray* attributesToReturn = [super layoutAttributesForElementsInRect:rect];
    for (UICollectionViewLayoutAttributes* attributes in attributesToReturn) {
        if (nil == attributes.representedElementKind) {
            NSIndexPath* indexPath = attributes.indexPath;
            attributes.frame = [self layoutAttributesForItemAtIndexPath:indexPath].frame;
        }
    }
    return attributesToReturn;
}

#define numColumns 2

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewLayoutAttributes* currentItemAttributes = [super layoutAttributesForItemAtIndexPath:indexPath];

    if (indexPath.item < numColumns) {
        CGRect f = currentItemAttributes.frame;
        f.origin.y = 0;
        currentItemAttributes.frame = f;
        return currentItemAttributes;
    }

    NSIndexPath* ipPrev = [NSIndexPath indexPathForItem:indexPath.item-numColumns 
                                              inSection:indexPath.section];
    CGRect fPrev = [self layoutAttributesForItemAtIndexPath:ipPrev].frame;
    CGFloat YPointNew = fPrev.origin.y + fPrev.size.height + 10;
    CGRect f = currentItemAttributes.frame;
    f.origin.y = YPointNew;
    currentItemAttributes.frame = f;

    return currentItemAttributes;
}

任何人都可以检查并看到,在您滚动一段时间后,您会得到一种奇怪的空白效果,这些空白最近被他们的单元格填充,类似于:

Anyone can check and see that after you scroll for a while, you get a strange effect of blank spaces that are filled lately by their cells,something like :

 1 2
 3 4
   6
   8

注意:5-7 稍后加载.

从单元格大小委托方法中删除随机高度,将其设置为恒定高度,解决了这个问题.
问题是:单元格的高度必须是动态的.

Removing the random height from the cell size delegate method, set it to be constant height, solves this issue.
Problem is: Cell's height must be dynamic.

将随机高度(int a)设置得更小,也会使问题消失,(<100),意味着单元格之间的距离高度越小,问题就越可能不会发生.

Setting the random height (int a) to be smaller, makes also the problem to disappear,(<100), means that the smaller the distance height between cells, more likely the problem will not occur .

EDIT3!

我已经设法在单元格之间设置了一个恒定的距离,而不是布局的子类,而是通过保存以前的单元格原点和高度,用我自己的记忆,所以我得到了恒定的间距,但问题又回来了再次!似乎如果单元格处于某种特定结构中,它会使创建单元格的回调方法不被及时调用!哇,我真的很想知道以前怎么没人见过这个..这是我在没有子类化的情况下创建间距的实现,这也导致了问题:

I have managed to set a constant distance between cells, not with subclass of the layout, but with my own memory by saving the previous cell origin and height, so i have got the constant spacing but the problem is back again ! seems that if the cells are in some certain structure, it makes the callback method that create cells, to not being called in time ! wow , i am really wondering how no one had seen this before .. here is my implementation to create spacing with no subclassing,that also cause the problem:

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

    static NSString *cellIdentifier=@"Cell";
    GridCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
    cell.textL.text=[NSString stringWithFormat:@"%ld",(long)indexPath.row];
    NSLog(@"%d",indexPath.row);


    if(indexPath.row>1)
    {
    NSIndexPath* ipPrev = [NSIndexPath indexPathForItem:indexPath.item-2 inSection:indexPath.section];

        float prey=[[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"y:%ld",(long)ipPrev.row]] floatValue];
        float preh=[[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"h:%ld",(long)ipPrev.row]] floatValue];


        cell.frame=CGRectMake(cell.frame.origin.x, preh+prey+10, cell.frame.size.width, cell.frame.size.height);

   [[NSUserDefaults standardUserDefaults] setFloat:cell.frame.origin.y forKey:[NSString stringWithFormat:@"y:%ld",(long)indexPath.row]];
   [[NSUserDefaults standardUserDefaults] setFloat:cell.frame.size.height forKey:[NSString stringWithFormat:@"h:%ld",(long)indexPath.row]];
    [[NSUserDefaults standardUserDefaults] synchronize];

    NSLog(@"this index:%d",indexPath.row);
    NSLog(@"this cell y:%f",cell.frame.origin.y);
   NSLog(@"this cell height:%f",cell.frame.size.height);
   NSLog(@"previous index:%ld",(long)ipPrev.row);
    NSLog(@"previous cell y: %@",[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"y:%ld",(long)ipPrev.row]]);
   NSLog(@"previous cell height: %@",[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"h:%ld",(long)ipPrev.row]]);
    NSLog(@"------------------------");
    }

    return cell;

}

推荐答案

当图像大于屏幕尺寸时,这似乎是 UICollectionView 中的一个严重错误.

Seems its a serious bug in UICollectionView, when images are bigger than screen size.

1 .UICollectionView 回退到 UIScrollView

2.大 UICollectionViewCell 的自定义布局消失

3.http:///stripysock.com.au/blog/2013/3/14/working-around-a-bug-in-uicollectionview

这么多的工作和时间,对于这个带有可重复使用细胞的愚蠢的苹果错误,除了令人头疼的许多奇怪的行为之外,什么也不会.

So much work and time, for this stupid bug of apple with the reusable cells that causes nothing but headache with so many strange behaviours.

对于没有问题的开发者,我可以说——只要尝试设置动态高度图像和 iPad 模拟器,你就会看到难以置信的错误.

For developers who didn't have the problem i can say- just try to set dynamic height images, and iPad simulator, and you will see bugs that are just unbelievable.

所以我没有答案,我将不得不自己用滚动视图来实现整个事情,因为我不想再次依赖诸如 PSTCollectionView

So no answer for me, i will have to implement the whole thing by my self with a scrollview ,since i dont want to be depended again on things such PSTCollectionView

这篇关于具有动态高度的 UICollectionView 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆