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

查看:128
本文介绍了具有动态高度的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 flowlayout,它将布局子类化以获得单元格之间的恒定间距,这是开始:

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稍后会加载。

EDIT1:

从单元格大小委托方法中删除随机高度,将其设置为恒定高度,解决了这个问题。

问题是:单元格的高度必须是动态的。

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.

EDIT2:
将随机高度(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!

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

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.

所以没有答案对我来说,我必须由我自己实施整个事情使用scrollview,因为我不想再依赖于这样的事情 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天全站免登陆