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

Ошибка подтверждения в UICollectionViewData validateLayoutInRect на ios7

Ошибка подтверждения в UICollectionViewData validateLayoutInRect на iOS7.

Я пытаюсь удалить все элементы UICollectionView один за другим, используя цикл for; Я разместил свой код ниже. Я удаляю элементы UICollectionView, используя deleteItemsAtIndexPaths. Он отлично работает на iOS6, но сбой в iOS7 с этим исключением:

Ошибка подтверждения в UICollectionViewData validateLayoutInRect

Я удаляю объект из collectionArray, затем self.collectionView, один за другим, используя indexPath. Когда я удаляю 4-й объект, он поднимает Assertion failure на iOS7. Здесь я использую performBatchUpdates.

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

try  {    
    for (int i=count-1; i>=0; i--)  {  
        [self.collectionView performBatchUpdates:^(void){  
            [collectionArray removeObjectAtIndex:i]; // First delete the item from you model   
            [self.collectionView deleteItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]]];  
        } completion:nil];
        [self.collectionView reloadData];
    }
}
@catch (NSException *exception) {
}
@finally {
}
4b9b3361

Ответ 1

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

UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
Collection1 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 50.0f) collectionViewLayout:flowLayout];
[Collection1 setDataSource:self];
[Collection1 setDelegate:self];
[self.view addSubview:Collection1];

Collection2 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, self.view.frame.size.height) collectionViewLayout:flowLayout];
Collection2.backgroundColor = [UIColor whiteColor];

Вместо этого, если я создаю новый макет потока для каждого UICollectionView, я избегаю этого сбоя. Надеюсь, это может помочь кому-то.

UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
Collection1 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 50.0f) collectionViewLayout:flowLayout];
[Collection1 setDataSource:self];
[Collection1 setDelegate:self];
[self.view Collection1];

UICollectionViewFlowLayout *flowLayoutVert = [[UICollectionViewFlowLayout alloc] init];
[flowLayoutVert setScrollDirection:UICollectionViewScrollDirectionVertical];
Collection2 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, self.view.frame.size.height) collectionViewLayout:flowLayoutVert];

Ответ 2

в iOS 10 вы должны отключить prefetchingEnabled:

// Swift
if #available(iOS 10, *) { 
    collectionView.prefetchingEnabled = false 
}

//Obj C
if ([self.collectionView respondsToSelector:@selector(setPrefetchingEnabled:)]) {
    self.collectionView.prefetchingEnabled = false;
}

Ответ 3

Похоже, вы, вероятно, захотите сделать это:

[self.CollectionView performBatchUpdates:^(void) {
  for (int i = count - 1; i >= 0; i--) {
    [collectionArray removeObjectAtIndex:i]; // First delete the item from you model
    [self.CollectionView deleteItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]]];
  }
} completion:nil];

Итак, все обновления выполняются вместе. В противном случае вы в конечном итоге попытаетесь выполнить несколько партий пакетных обновлений друг над другом.

Ответ 4

попробуйте вызвать [yourCollectionView.collectionViewLayout invalidateLayout];

Ответ 5

В моем случае отсутствовал следующий делегат:

func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

Ответ 6

layout lifecycle

Вам следует реализовать invalidateLayout в layoutClass и удалить всевозможные элементы UICollectionViewLayoutAttributes в вашей конфигурации.

- (void)invalidateLayout{
  [super invalidateLayout];
  [self.itemsAttributes removeAllObjects];
}

Ответ 7

Вы должны реализовать invalidateLayout в своем классе макета и удалить все типы UICollectionViewLayoutAttributes элементов в вашем config.

- (void)invalidateLayout{
  [super invalidateLayout];
  [self.itemsAttributes removeAllObjects];
}

Для лучшего способа реализации invalidateLayoutWithContext см. подробнее о UICollectionViewLayoutInvalidationContext.

От Документация разработчика Apple:

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

Ответ 8

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    [collectionView.collectionViewLayout invalidateLayout];
    return 1;
}