uicollectionview 在重新加载数据后立即选择一个项目?

Posted

技术标签:

【中文标题】uicollectionview 在重新加载数据后立即选择一个项目?【英文标题】:uicollectionview select an item immediately after reloaddata? 【发布时间】:2013-01-08 10:19:12 【问题描述】:

调用-[UICollectionView reloadData] 后,单元格显示需要一些时间,因此在调用reloadData 后立即选择项目不起作用。有没有办法在reloadData之后立即选择一个项目?

【问题讨论】:

这方面有什么更新吗?我遇到了同样的问题,试图在 UICollectionView 加载期间创建一个选择。 【参考方案1】:

按照this answer 的思路,我发现在reloadData 之后调用layoutIfNeeded 似乎在我对collectionView 执行其他操作之前有效地“刷新”了重新加载:

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

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

【讨论】:

【参考方案2】:

迅捷之道:

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: [])
        

【讨论】:

【参考方案3】:

我正在处理collectionView: cellForItemAtIndexPath: 中的单元格选择。我发现的问题是,如果单元格不存在,只需调用selectItemAtIndexPath: animated: scrollPosition: 就不会真正选择该项目。

相反,您必须这样做:

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

【讨论】:

【参考方案4】:

不要使用 reloadData

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

【讨论】:

当 UICollectionView 有很多项目时,我发现动画更新调用与 reloadData 相比存在巨大的性能问题。【参考方案5】:

苹果说:

你不应该在动画块中间调用这个方法 插入或删除项目的位置。插入和删除 自动使表的数据得到适当的更新。

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

希望对你有帮助。

【讨论】:

【参考方案6】:

确保您在主线程上调用reloadData。这可能是您的单元格更新延迟的原因。

【讨论】:

而the answer to this question 展示了如何做到这一点。【参考方案7】:

我在 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;
        
    

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

【讨论】:

【参考方案8】:

这对我有用:

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

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

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

【讨论】:

【参考方案9】:

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

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

【讨论】:

我不喜欢这个解决方案,因为它需要任意数量的时间。我们如何知道reloadData 何时完成?这个好像没办法查询。

以上是关于uicollectionview 在重新加载数据后立即选择一个项目?的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionview 在使用 Core Data 保存实体后重新加载数据

即使在删除部分数据并重新加载 UICollectionView 后,部分标题仍然存在

如果在重新加载期间触摸单元格,则重新加载后无法选择 UICollectionView 单元格

重新加载数据后根据要求更新后未显示 uicollectionview 单元格

重新加载数据后未调用 UICollectionView 数据源方法

使用 UIImagePicker 拾取图像后重新加载 UICollectionView 的正确时间和位置