Uicollectionview выбрать элемент сразу после reloaddata?

После вызова -[UICollectionView reloadData] для отображения ячеек требуется некоторое время, поэтому выбор элемента сразу после вызова reloadData не работает. Есть ли способ выбрать элемент сразу после reloadData?

Ответ 1

Вдоль строк этот ответ я обнаружил, что вызов layoutIfNeeded после reloadData, казалось, эффективно "флешировал" перезагрузку, прежде чем я делаю другие вещи в collectionView

[self.collectionView reloadData];
[self.collectionView layoutIfNeeded];
...

На странице я нашел это решение, некоторые комментаторы указали, что он не работает для них на iOS 9, но для меня это было хорошо, поэтому ваш пробег может отличаться.

Ответ 2

Я обрабатываю выбор ячеек в collectionView: cellForItemAtIndexPath:. Проблема, которую я обнаружил, заключалась в том, что если ячейка не существует, просто вызов selectItemAtIndexPath: animated: scrollPosition: фактически не будет выбирать элемент.

Вместо этого вам нужно сделать:

cell.selected = YES;
[m_collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];

Ответ 3

Не используйте reloadData​​p >

Используйте - (void)performBatchUpdates:(void (^)(void))updates completion:(void (^)(BOOL finished))completion вместо этого. Блок завершения выполняется после завершения анимации для вставки/удаления ячеек и т.д. Вы можете поместить вызов reloadData в блок (void (^)(void))updates

Ответ 4

Apple говорит:

Вы не должны вызывать этот метод в середине блоков анимации где элементы вставляются или удаляются. Вставки и удаления автоматически заставляют данные таблиц обновляться соответствующим образом.

Фактически, вы не должны вызывать этот метод в середине любой анимации (включая UICollectionView в прокрутке).

Итак, вы можете использовать:

[self.collectionView setContentOffset:CGPointZero animated:NO];
[self.collectionView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];

или отметьте уверенность в какой-либо анимации, а затем вызовите reloadData; или

[self.collectionView performBatchUpdates:^{
//insert, delete, reload, or move operations
} completion:nil];

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

Ответ 5

Быстрый способ:

let selected = collectionView.indexPathsForSelectedItems()
collectionView.performBatchUpdates({ [weak self] in
    self?.collectionView.reloadSections(NSIndexSet(index: 0))
    }) { completed -> Void in
        selected?.forEach { [weak self] indexPath in
            self?.collectionView.selectItemAtIndexPath(indexPath, animated: false, scrollPosition: [])
        }
}

Ответ 6

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

Ответ 7

Я обработал его на делегате colelctionView willDisplayCell. Идея: необходима временная переменная, чтобы указать, что начальная прокрутка уже выполнена или нет (scrollIsRequired). Когда отобразится последняя видимая ячейка, мы можем прокрутить до нужной ячейки и установить эту переменную, чтобы избежать прокрутки снова.

- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{

    //Perform any configuration

    if (CGRectGetMaxX(collectionView.frame) <= CGRectGetMaxX(cell.frame)) {
        // Last visible cell
        if (self.scrollIsRequired) {
            [self.collectionView selectItemAtIndexPath:[NSIndexPath indexPathForItem:self.initiallySelectedRepresentativeVerse inSection:0] animated:YES scrollPosition:UICollectionViewScrollPositionLeft];
            self.scrollIsRequired = NO;
        }
    }
}

Он работал у меня как шарм.

Ответ 8

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

Я сохранил ссылку выбранного пути индекса и переопределял функцию reloadData:

override func reloadData() {
    super.reloadData()
    self.selectItem(at: self.selectedIndexPath, animated: false, scrollPosition: UICollectionViewScrollPosition())
}

Я пробовал делать это с помощью indexPathForSelectedItems, но он создавал бесконечный цикл при загрузке коллекции.

Ответ 9

создайте метод, который выполняет выбор и вызывает его с помощью функции performSelector после вызова reload, например:

[self performSelector:@selector(selectIt) withObject:self afterDelay:0.1];