重新加载并滚动到特定的集合视图单元格
Posted
技术标签:
【中文标题】重新加载并滚动到特定的集合视图单元格【英文标题】:Reload and Scroll to a specific Collection View cell 【发布时间】:2013-11-05 12:16:13 【问题描述】:我正在编写一个应用程序,它使用 UICollectionView 在 CollectionView 单元格中显示一些内容。使用捏合手势,需要重新加载集合视图。我能够根据捏合手势处理内容的变化。现在,在捏合手势开始时,集合视图需要重新加载并滚动到特定索引。为此,我调用了这样的函数:
[tempCollectionView reloadData];
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(scrollToItem) userInfo:nil repeats:YES];
[OR]
[self performSelector:@selector(scrollToItem) withObject:nil afterDelay:0.0];
- (void) scrollToItem
if (m_selectedCellIndex == -1)
NSLog(@"cell return");
return;
NSIndexPath *iPath = [NSIndexPath indexPathForItem:m_selectedCellIndex inSection:0];
[tempLocalFilesCollectionView scrollToItemAtIndexPath:iPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO];
LocalFilesCollectionViewCell *cell = (LocalFilesCollectionViewCell *) [m_tempLocalFilesCollectionView cellForItemAtIndexPath: iPath];
if (cell)
CGPoint p = [tempCollectionView convertPoint: cell.center fromView: tempCollectionView];
NSLog(@"center: %f, %f, %f, %f", cell.center.x, cell.center.y, p.x, p.y);
else
NSLog(@"Not found");
但是滚动不起作用。它因错误“尝试滚动到无效的索引路径”而崩溃。很明显 tempCollectionView 没有准备好滚动的任何单元格。
重新加载完成后如何滚动到索引路径?任何帮助都会很棒!
【问题讨论】:
您应该可以在刷新集合视图后立即调用滚动方法。这是您的索引路径的问题。你打印出iPath
的行了吗?它比您的浏览量大还是小?
iPath 的行看起来是正确的,在单元格计数的范围内。不仅仅是滚动,我的目的是通过这个来获得单元格的位置。在上述方法中,单元格以 nil 形式返回。我在这里错过了什么吗?
您正在调用 scrollToItem 两次。一次延迟,一次没有延迟。有可能 reloadData 没有立即完成调用,以便有任何索引路径可以使用。
我忘记在此处放置 OR,我正在尝试使用其中编写的两个语句之一进行调用。谢谢!
【参考方案1】:
试试这个
BOOL _viewDidLayoutSubviewsForTheFirstTime = YES;
- (void)viewDidLoad
[super viewDidLoad];
_viewDidLayoutSubviewsForTheFirstTime = YES;
- (void)viewDidLayoutSubviews
[super viewDidLayoutSubviews];
// Only scroll when the view is rendered for the first time
if (_viewDidLayoutSubviewsForTheFirstTime)
_viewDidLayoutSubviewsForTheFirstTime = NO;
// Calling collectionViewContentSize forces the UICollectionViewLayout to actually render the layout
[self.collectionView.collectionViewLayout collectionViewContentSize];
// Now you can scroll to your desired indexPath or contentOffset
[self.collectionView scrollToItemAtIndexPath:yourDesiredIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO];
希望对大家有帮助
【讨论】:
【参考方案2】:到目前为止我发现的最佳解决方案是像这样使用CATransaction
:
CATransaction.begin()
CATransaction.setCompletionBlock
collectionView.scrollToItem(...)
collectionView.reloadData()
CATransaction.commit()
【讨论】:
【参考方案3】:如果你想垂直滚动,你可以试试这个异步代码
dispatch_async(dispatch_get_main_queue(), ^
[_yourCollectionView reloadData];
[_yourCollectionView reloadInputViews];
[_yourCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:5 inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES];
);
并替换为
[_yourCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:5 inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
如果你想让你的滚动视图水平滚动
将 indexPathForRow 和 inSection 的数量替换为您要滚动到的行号,并记住 NSIndexPath 用于 UITableView 和 UICollectionView 通常带有 inSection 引用 Convert NSInteger to NSIndexpath
【讨论】:
以上是关于重新加载并滚动到特定的集合视图单元格的主要内容,如果未能解决你的问题,请参考以下文章
UICollectionView 单元格在可见时不断重新加载