[英]UICollectionView doesn't update immediately when calling reloadData, but randomly after 30-60 seconds
[英]uicollectionview select an item immediately after reloaddata?
在调用-[UICollectionView reloadData]
,显示单元格需要一些时间,因此在调用reloadData
之后立即选择一个项目不起作用。 有没有办法在reloadData
之后立即选择一个项目?
根据这个答案,我发现在我对collectionView执行其他操作之前,在reloadData
之后调用layoutIfNeeded
似乎有效地“刷新”了重新加载:
[self.collectionView reloadData];
[self.collectionView layoutIfNeeded];
...
在页面上我找到了这个解决方案,一些评论者表示它在iOS 9上没有对他们有效,但它对我来说没问题所以你的里程可能会有所不同。
我正在处理collectionView: cellForItemAtIndexPath:
的单元格选择collectionView: cellForItemAtIndexPath:
. 我发现的问题是,如果单元格不存在,只需调用selectItemAtIndexPath: animated: scrollPosition:
实际上不会选择该项目。
相反,你必须这样做:
cell.selected = YES;
[m_collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];
不要使用reloadData
使用- (void)performBatchUpdates:(void (^)(void))updates completion:(void (^)(BOOL finished))completion
。 在完成单元插入/删除等的动画之后执行完成块。 您可以在(void (^)(void))updates
块中调用reloadData
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];
希望这对你有所帮助。
Swift方式:
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: [])
}
}
确保在主线程上调用reloadData
。 这可能是导致细胞更新延迟的原因。
我在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;
}
}
}
它对我来说就像一个魅力。
这对我有用:
我保留了所选索引路径的引用并覆盖了reloadData函数:
override func reloadData() {
super.reloadData()
self.selectItem(at: self.selectedIndexPath, animated: false, scrollPosition: UICollectionViewScrollPosition())
}
我尝试使用indexPathForSelectedItems,但它在集合视图加载时创建了一个无限循环。
创建一个执行选择的方法,并在调用reload后使用performSelector调用它;
[self performSelector:@selector(selectIt) withObject:self afterDelay:0.1];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.