重新加载并滚动到特定的集合视图单元格

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];

如果你想让你的滚动视图水平滚动

indexPathForRowinSection 的数量替换为您要滚动到的行号,并记住 NSIndexPath 用于 UITableView 和 UICollectionView 通常带有 inSection 引用 Convert NSInteger to NSIndexpath

【讨论】:

以上是关于重新加载并滚动到特定的集合视图单元格的主要内容,如果未能解决你的问题,请参考以下文章

如何将集合视图单元格滚动到可见区域的中间

UICollectionView 单元格在可见时不断重新加载

无法理解集合视图中的恢复单元格

滚动到一个集合视图到一个物种索引

如何在不重新加载图像的情况下重新加载 collectionview 单元格

重新加载uitableview后滚动表格视图