Подтвердить что ты не робот

ContentSize не обновляется после вызова reloadData в UICollectionView

Кто-нибудь знает, почему contentSize не обновляется сразу после вызова reloadData в UICollectionView?

Если вам нужно знать contentSize, лучшая работа, которую я нашел, это следующее:

[_collectionView reloadData];

double delayInSeconds = 0.0001;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(DISPATCH_TIME_NOW, dispatch_get_main_queue(), ^(void)
    {
        // TODO: Whatever it is you want to do now that you know the contentSize.
    });

Очевидно, что это довольно хрупкий взлом, который делает предположения о внедрении Apple, но до сих пор он оказался достаточно надежным.

Есть ли у кого-нибудь другие способы обхода или знания о том, почему это происходит? Я обсуждаю отправку радара, потому что я не могу понять, почему они не могут вычислить contentSize в том же цикле запуска. Вот как UITableView работал для всей своей реализации.

EDIT: этот вопрос используется для ссылки на метод setContentOffset внутри блока, потому что я хочу прокрутить представление коллекции в моем приложении. Я удалил вызов метода, потому что ответы людей были сосредоточены на том, почему я не использовал scrollToItemAtIndexPath внутри того, почему contentSize не обновляется.

4b9b3361

Ответ 1

Чтобы получить размер содержимого после перезагрузки, попробуйте вызвать collectionViewContentSize объекта макета. Меня устраивает.

Ответ 2

Это сработало для меня:

[self.collectionView.collectionViewLayout invalidateLayout];
[self.collectionView.collectionViewLayout prepareLayout];

Ответ 3

Изменить: я только что протестировал это, и действительно, когда данные изменятся, мое первоначальное решение выйдет из строя со следующим:

"Недопустимое обновление: недопустимое количество элементов в разделе 0. Количество элементов, содержащихся в существующем разделе после обновления (7), должно быть равно количеству элементов, содержащихся в этом разделе, перед обновлением (100), плюс или минус количество элементов, вставленных или удаленных из этого раздела (0 вставлено, 0 удалено) и плюс или минус количество элементов, перемещенных в или из этого раздела (0 перемещен, 0 перемещен).

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

NSArray *indexPaths = @[indexPath1, indexPath2];
[self.collectionView performBatchUpdates:^() 
{
    [self.collectionView insertItemsAtIndexPaths:indexPaths];
} completion:^(BOOL finished) {
    // TODO: Whatever it is you want to do now that you know the contentSize.
}];

Ниже представлено отредактированное решение моего первоначального ответа Kernix, которое, как я думаю, не гарантируется.

Попробуйте выполнитьBatchUpdates: завершение: в UICollectionView. У вас должен быть доступ к обновленным свойствам в блоке завершения. Это будет выглядеть так:

[self.collectionView reloadData];
[self.collectionView performBatchUpdates:^() 
{

} completion:^(BOOL finished) {
    // TODO: Whatever it is you want to do now that you know the contentSize.
}];

Ответ 4

Сначала вызовите prepareLayout, а затем вы получите правильный контент. Размер:

[self.collectionView.collectionViewLayout prepareLayout];