13

After calling -[UICollectionView reloadData] it takes some time for cells to be displayed, so selecting an item immediately after calling reloadData does not work. Is there a way to select an item immediately after reloadData?

4

9 回答 9

13

按照这个答案,我发现在我对 collectionView 做其他事情之前调用layoutIfNeededafterreloadData似乎有效地“刷新”了重新加载:

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

在我找到这个解决方案的页面上,一些评论者表示它在 iOS 9 上不适用于他们,但对我来说没问题,所以你的里程可能会有所不同。

于 2016-07-26T00:30:24.700 回答
4

不要使用 reloadData

改为使用- (void)performBatchUpdates:(void (^)(void))updates completion:(void (^)(BOOL finished))completion。完成块在单元格插入/删除等动画完成后执行。您可以在(void (^)(void))updates块中调用 reloadData

于 2013-05-14T19:02:12.663 回答
4

苹果 说:

您不应在插入或删除项目的动画块中间调用此方法。插入和删除会自动导致表的数据得到适当的更新。

事实上,你不应该在任何动画的中间调用这个方法(包括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];

希望这对你有帮助。

于 2014-05-05T17:25:24.863 回答
4

我正在处理collectionView: cellForItemAtIndexPath:. 我发现的问题是,如果单元格不存在,简单地调用selectItemAtIndexPath: animated: scrollPosition:实际上不会选择该项目。

相反,您必须这样做:

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

于 2013-03-14T16:00:44.767 回答
4

迅速的方式:

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: [])
        }
}
于 2016-03-01T16:29:38.080 回答
0

Make sure you're calling reloadData on the main thread. That could be the cause for the delay in your cell updates.

于 2013-01-14T06:09:08.833 回答
0

我在 willDisplayCell colelctionView 委托上处理了它。这个想法:需要一个临时变量来指定初始滚动是否已经执行(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;
        }
    }
}

它对我来说就像一种魅力。

于 2015-01-13T13:32:53.390 回答
0

这对我有用:

我保留了所选索引路径的引用并覆盖了 reloadData 函数:

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

我尝试使用 indexPathForSelectedItems 执行此操作,但它在集合视图加载时创建了一个无限循环。

于 2017-06-15T15:44:09.647 回答
-6

创建一个进行选择的方法,并在调用 reload 后使用 performSelector 调用它,例如;

[self performSelector:@selector(selectIt) withObject:self afterDelay:0.1];
于 2013-01-08T10:30:53.853 回答