Ошибка UICollectionView с динамической высотой

Поскольку я боролся с этой проблемой в течение 3 дней и уже дважды спрашивал об этом, но, возможно, это было неясно, я решил исследовать проблему и обнаружил ошибочное поведение с этим представлением.

Я покажу весь простой код, чтобы каждый мог воспроизвести ошибку (iPad Air).

Я устанавливаюcollectionView flowlayout, который подклассирует макет, чтобы получить постоянный интервал между ячейками, и вот начало:

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

Тогда настроить моих делегатов так просто :(высота динамическая )

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

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

Любой может проверить и увидеть, что после некоторой прокрутки вы получаете странный эффект пустых пространств, которые в последнее время заполняются своими ячейками, что-то вроде:

 1 2
 3 4
   6
   8

ПРИМЕЧАНИЕ: 5-7 загружаются позже.

EDIT1:

Устранение случайной высоты из метода делегата размера ячейки, установка постоянной высоты, решает эту проблему.
Проблема в том, что высота ячейки должна быть динамической.

EDIT2: Установка случайной высоты (int a) на меньшую величину также приводит к исчезновению проблемы (<100), что означает, что чем меньше расстояние между ячейками, тем больше вероятность того, что проблема не возникнет.

РЕДАКТИРОВАТЬ3!

Мне удалось установить постоянное расстояние между ячейками, не с подклассом макета, а с моей собственной памятью, сохранив предыдущее происхождение и высоту ячейки,так что у меня есть постоянный интервал, но проблема снова ! кажется, что если ячейки находятся в некоторой определенной структуре, это делает метод обратного вызова, который создает ячейки, чтобы не вызываться вовремя! вау, мне действительно интересно, как никто не видел этого раньше ... вот моя реализация для создания интервалов без подклассов, которые также вызывают проблему:

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

}

Ответы на вопрос(1)

Ваш ответ на вопрос