UICollectionView с ячейками для самостоятельной калибровки изменяет размеры ячеек во время вставки/удаления анимации

У меня есть простой UICollectionView с UICollectionViewFlowLayout, который использует автозапуск, чтобы разрешать ячейки для самостоятельной калибровки. Вещи отлично работают в статическом макете, но когда я вставляю или удаляю ячейки, ячейки изменяются до предполагаемого размера:

[self.collectionView performBatchUpdates:^{
    [self.collectionView insertItemsAtIndexPaths:@[indexPath]];
} completion:nil];

Помимо настройки расчетного размера, например:

layout.estimatedItemSize = CGSizeMake(88.0, 88.0);

Я не делаю ничего необычного в представлении коллекции. Все настроено с помощью раскадровки.

Как я могу избежать этого изменения размера? Я ориентируюсь только на iOS 8.0 и выше, поэтому он должен поддерживаться.

example of the problem

Ответы

Ответ 1

Прямолинейное решение заключается в реализации метода UICollectionViewDelegateFlowLayout

 func collectionView(_ collectionView: UICollectionView, layoutcollectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
      // calculate string size here
}

И после вставки или удаления ячеек убедитесь, что вы отменили макет, чтобы снова вызвать метод делегата.

collectionView.performBatchUpdates({ 
    // insert/delete items here
}) { (success: Bool) in
    collectionView.collectionViewLayout.invalidateLayout()
}

Ответ 2

  • Задайте свойство estimatedItemSize для определенного размера.

  • В вашем настраиваемом классе UICollectionView переопределить тип метода и размер макета кеша, заданный супер.

    -(UICollectionViewLayoutAttributes*)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes
    {
        UICollectionViewLayoutAttributes * superAttr = [super preferredLayoutAttributesFittingAttributes:layoutAttributes];
       //Cache size which is returned by super (superAttr.frame.size) since super calculates the correct size for auto size cells.
        return superAttr;
    }
    

3.In sizeForItemAtIndexPath возвращает кешированный размер, если доступен другой расчетный размер.

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath 
{
    //return cached size if available else the estimated size
}