UICollectionview scrollToItemAtIndexPath,在动画完成之前不加载可见单元格
UICollectionview scrollToItemAtIndexPath, not loading visible cells until animation complete
我有一个 UICollectionView
有 142 个单元格。 7.5 随时可见。
我正在将单元格从 indexPath
0 移动到 100。
但我也想滚动到那个新位置。
下面的代码工作正常。但它为移动和滚动设置动画,然后加载 central/moved 单元格前后的单元格。
我认为这是因为细胞是可重复使用的。但是对于 142,我无法预加载所有这些
这不是最好的效果,我想预加载新位置周围的单元格,indexPath
100之前4个之后4个,然后看移动和滚动的动画。你能帮忙吗?
UIView.animateWithDuration(animationSpeed, animations: {() -> Void in
self.collectionView.layoutIfNeeded()
self.collectionView.scrollToItemAtIndexPath(NSIndexPath(forItem:self.indexPathSelected.row,
inSection:0),
atScrollPosition: .CenteredHorizontally,
animated: true)
})
我找到的唯一答案是在动画中添加几秒钟。这样当滚动到达时单元格被加载
我使用 dispatch_async 来更新 UI 并且它有效。
let numberOfSections = self.collectionView.numberOfSections()
let numberOfRows = self.collectionView.numberOfItemsInSection(numberOfSections-1)
if numberOfRows > 0 {
dispatch_async(dispatch_get_main_queue(), {
let indexPath = NSIndexPath(forRow: numberOfRows-1, inSection: (numberOfSections-1))
self.collectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: .Bottom, animated: true)
})
}
Swift 3.0 OR up
add "view.layoutIfNeeded()" before implementing scrollToItem method, Ideally in viewWillAppear
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
view.layoutIfNeeded()
colView.scrollToItem(at: IndexPath(item: 4, section: 0), at: .centeredHorizontally, animated: true)}
我找到的最佳解决方案是使用 DispatchQueue
。
Swift 4.2:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let index = items.firstIndex(of: preSelectedItem) {
DispatchQueue.main.async {
self.collectionView.scrollToItem(at: IndexPath(item: index, section: 0), at: .top, animated: false)
}
}
}
@Politta 的回答是正确的。以下是如何在 Objective C 中实现您想要的内容:
- (void)scrollToBottomWithoutAnimation{
NSInteger lastVisibleRowIndex = (NSInteger)self.myItems.count - 1;
NSIndexPath *lastVisibleIndexPath = [NSIndexPath indexPathForRow: lastVisibleRowIndex inSection:0];
[self.collectionView scrollToItemAtIndexPath:lastVisibleIndexPath atScrollPosition: UICollectionViewScrollPositionCenteredVertically animated:NO];
}
在您的 viewWillAppear 方法中:
dispatch_async(dispatch_get_main_queue(), ^{
[self scrollToBottomWithoutAnimation];
});
你需要先调用[self.view layoutIfNeeded]
再调用scrollToBottomWithoutAnimation
我有一个 UICollectionView
有 142 个单元格。 7.5 随时可见。
我正在将单元格从 indexPath
0 移动到 100。
但我也想滚动到那个新位置。
下面的代码工作正常。但它为移动和滚动设置动画,然后加载 central/moved 单元格前后的单元格。 我认为这是因为细胞是可重复使用的。但是对于 142,我无法预加载所有这些
这不是最好的效果,我想预加载新位置周围的单元格,indexPath
100之前4个之后4个,然后看移动和滚动的动画。你能帮忙吗?
UIView.animateWithDuration(animationSpeed, animations: {() -> Void in
self.collectionView.layoutIfNeeded()
self.collectionView.scrollToItemAtIndexPath(NSIndexPath(forItem:self.indexPathSelected.row,
inSection:0),
atScrollPosition: .CenteredHorizontally,
animated: true)
})
我找到的唯一答案是在动画中添加几秒钟。这样当滚动到达时单元格被加载
我使用 dispatch_async 来更新 UI 并且它有效。
let numberOfSections = self.collectionView.numberOfSections()
let numberOfRows = self.collectionView.numberOfItemsInSection(numberOfSections-1)
if numberOfRows > 0 {
dispatch_async(dispatch_get_main_queue(), {
let indexPath = NSIndexPath(forRow: numberOfRows-1, inSection: (numberOfSections-1))
self.collectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: .Bottom, animated: true)
})
}
Swift 3.0 OR up
add "view.layoutIfNeeded()" before implementing scrollToItem method, Ideally in viewWillAppear
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
view.layoutIfNeeded()
colView.scrollToItem(at: IndexPath(item: 4, section: 0), at: .centeredHorizontally, animated: true)}
我找到的最佳解决方案是使用 DispatchQueue
。
Swift 4.2:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let index = items.firstIndex(of: preSelectedItem) {
DispatchQueue.main.async {
self.collectionView.scrollToItem(at: IndexPath(item: index, section: 0), at: .top, animated: false)
}
}
}
@Politta 的回答是正确的。以下是如何在 Objective C 中实现您想要的内容:
- (void)scrollToBottomWithoutAnimation{
NSInteger lastVisibleRowIndex = (NSInteger)self.myItems.count - 1;
NSIndexPath *lastVisibleIndexPath = [NSIndexPath indexPathForRow: lastVisibleRowIndex inSection:0];
[self.collectionView scrollToItemAtIndexPath:lastVisibleIndexPath atScrollPosition: UICollectionViewScrollPositionCenteredVertically animated:NO];
}
在您的 viewWillAppear 方法中:
dispatch_async(dispatch_get_main_queue(), ^{
[self scrollToBottomWithoutAnimation];
});
你需要先调用[self.view layoutIfNeeded]
再调用scrollToBottomWithoutAnimation