Ошибка утверждения UICollectionView для устаревших данных

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

*** Assertion failure in -[UICollectionViewData validateLayoutInRect:], 
/SourceCache/UIKit_Sim/UIKit-2891.1/UICollectionViewData.m:341
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', 
reason: 'UICollectionView recieved layout attributes for a cell with an 
index path that does not exist: <NSIndexPath: 0xb141c60> {length = 2, path = 0 - 2}

В этом случае существующий список изображений был равен 5, а новый список отсчетов был равен 2. Таким образом, когда он попал на третье изображение - произошло исключение - это указывает на то, что пользовательский интерфейс CollectionViewDataDelegate не знал об изменении в поток данных.

Любые предложения о том, как убедиться, что новые изображения будут ссылаться на UICollectionView? Конечно, я назвал reloadData...

Спасибо

Ответ 1

Я запускаю ту же проблему. Код работает под номером 6.1 и падает до 7.0 Я решил проблему следующим образом:

В функции

-(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView

Я звоню

[myCollectionView.collectionViewLayout invalidateLayout];

Вот и все.

Ответ 2

Оба Dominic Sander и user1544494 верны, и их решения хороши.

К сожалению, я заметил, что если вы установите minimumLineSpacingForSectionAtIndex или minimumInteritemSpacingForSectionAtIndex, внешний вид вашей коллекцииView будет разорван (рано или поздно).

Ввод invalidateLayout в viewWillLayoutSubviews отвечает на этот вопрос и помогает сохранить внешний вид viewCollection.

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    [viewCollection.collectionViewLayout invalidateLayout];
}

Ответ 3

С iOS 10 и 11 это помогает:

collectionView.reloadData()
collectionView.collectionViewLayout.invalidateLayout()

Недопустимый макет должен быть ПОСЛЕ перезагрузки данных.

Ответ 4

Это просто. Точно так же, как приговор.

'UICollectionView recieved layout attributes for a cell with an 
index path that does not exist: <NSIndexPath: 0xb141c60> {length = 2, path = 0 - 2}

Это означает, что на dataSouce нет indexPath (0,2). Но ваш UICollectionViewLayout возвращает UICollectionViewLayoutAttributes для indexPath (0,2).

Вы должны вернуть UICollectionViewLayoutAttributes, только существует только в dataSouce.


Я думаю, что он был изменен с iOS7.

Ответ 5

Моя проблема заключалась в том, что у меня было два UICollectionViews внутри одного UIViewController. И у меня были оба UICollectionViews, связанные с тем же подклассом UICollectionViewLayout. Я исправил эту проблему, изменив каждый UICollectionView, чтобы иметь свой собственный подкласс UICollectionViewLayout.

Источник: Этот вопрос

Ответ 6

Я исправил этот сбой, обновив исходный источник данных коллекции:

- (NSInteger)collectionView:(UICollectionView *)collectionView
     numberOfItemsInSection:(NSInteger)section
{
    [collectionView.collectionViewLayout invalidateLayout];
    return collectionArray.count;
}

Ответ 7

У меня был такой же крах.

В моем приложении проблема заключалась в том, что я не очистил массив с помощью UICollectionViewLayoutAttributes. Я использую его в методе prepareLayout() для хранения атрибута layout для каждой ячейки.

var itemAttributes: Array<UICollectionViewLayoutAttributes> = Array<UICollectionViewLayoutAttributes>()

Только с self.itemAttributes.removeAll() в первой строке prepareLayout он работает.

Ответ 8

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

[collectionView reloadData];

//forces the layout attributes to be recalculated for new data
[collectionView.collectionViewLayout invalidateLayout];

Ответ 9

Решение, которое я нашел, состояло в том, чтобы гарантировать, что indexPath, который я создавал в методе layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]?, действителен для строки. Раньше я использовал (где i мой счетчик циклов):

var indexPath = NSIndexPath(index: i)
var attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)

Но обновив его, чтобы использовать следующее, он решил:

var indexPath = NSIndexPath(forRow: i, inSection: 0)!
var attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)

Ответ 10

Мне удалось решить эту проблему, создав подкласс UICollectionViewFlowLayout и переопределив этот метод для возврата YES:

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}

Ответ 11

Убедитесь, что вы обновили contentSize вашего collectionViewLayout. Поэтому после получения новых изображений (2 вместо 5) пересчитайте contentSize и установите его.

Ответ 12

Я столкнулся с этой проблемой, и это было довольно неприятно. Мое исправление заключается в том, чтобы забыть о UICollectionViewController и использовать вместо него регулярный UIViewController с UICollectionView внутри.

Ответ 13

У меня тоже была эта ошибка, и я нашел обходной путь. Для меня UICollectionView запускал это под iOS 7, отлично работая на iOS 8.

Проверьте эту статью: Что вызывает этот сбой iOS? UICollectionView получил атрибуты макета для ячейки с отсутствием пути указателя

В 2 словах: Авто-макет. Отключите его в представлении, содержащем UICollectionView, и для меня он работал.

Ответ 14

CollectionViewLayout кэширует атрибуты макета. Вполне возможно. Создайте новый экземпляр collectionViewLayout и назначьте его в collectionview.collectionViewLayout Таким образом, все кэшированные атрибуты будут очищаться до перезагрузки Ваша проблема может быть решена. Работала для меня, особенно когда вы используете другие библиотеки collectionViewLayout.

Ответ 15

У меня была аналогичная проблема (с использованием Swift2.0, XCode 7).

Приложение разбилось с помощью UICollectionView received layout attributes for a cell with an index path that does not exist...

В моем случае, поскольку я использовал раскадровку, оказалось, что я забыл подключить IBOutlet, который был определен в моем viewController, с фактическим набором CollectionView, определенным в раскадровке. Подключение двух исправлено.

Ответ 16

Я понял это. Если вы используете nib/xib для организации UITableViewCell и вложенных UICollectionView, вы можете избежать этой ошибки, переопределив этот метод.

- (void)prepareForReuse {

    [super prepareForReuse];
    [self.collectionView.collectionViewLayout invalidateLayout];
}

Надеюсь, что это поможет.

Ответ 17

Это означает, что на dataSouce нет indexPath (0,2). Но ваш UICollectionViewLayout возвращает UICollectionViewLayoutAttributes для indexPath (0,2). По TopChul

Это правильно! Для меня проблема возникла из-за того, что я использую тот же макет коллекции (экземпляр) для двух collectionView! Так что макет путается между двумя коллекциями View.

Он отлично работает после того, как я использую разный макет между различными представлениями коллекции.

Ответ 18

Я столкнулся с чем-то похожим при попытке дублировать представление коллекции в другой раскадровки.

'UICollectionView получил атрибуты макета для ячейки с индексом путь, который не существует: {length = 2, path = 1 - 0} '

Сначала я ищу быстрое исправление. Протестированные копии вставляют различные ответы StackOverflow.

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

Затем я обнаружил, что класс контроллера классов забыл соответствовать UICollectionViewDataSource. Хотя dataSource был подключен в раскадровке, но, вероятно, класс контроллера просмотра будет отключен, например if let ds = dataSource as? UICollectionViewDataSource {ds.numberOfSections...}, который будет терпеть неудачу.

Итак, я добавил соответствие UICollectionViewDataSource, и все работает нормально. Мое предположение может быть неточным. Но урок есть всякий раз, когда есть ошибка, с которой вы не знакомы, успокоиться и понять ее. UICollectionView получил атрибуты макета для ячейки с отсутствующим указательным путем, это означает, что именно это говорит. Не так ли? Не пытайтесь найти серебряную пулю, как и многие из ответов здесь. Они все здорово, но ваш код - настоящее место битвы.

Ответ 19

Я сталкиваюсь с той же проблемой, когда использую UICollectionViewFlowLayout как CollectionView collectionViewLayout.

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

Ответ 20

В моем случае у меня был пользовательский UICollectionViewFlowLayout. После удаления ячеек из collectionView приложение упало. Исправление заключалось в removeAll() вычисленных ранее атрибутов. Итак, первая строка после override func prepare() - arrayHoldingYourAttributes.removeAll().

Ответ 21

Холло, у меня такая же проблема, в то время как вставка коллекцииView в другую коллекциюView и reloadData в основной очереди. Наконец, я reloadData перед новым преобразованием данных в collectionView.

dispatch_async(dispatch_get_main_queue(), ^{
    [_collectionView reloadData];
});

_notes = notes;

[_collectionView reloadData];