简体   繁体   English

保持UITableView和UICollectionView滚动位置同步

[英]Keeping UITableView and UICollectionView scroll position in sync

I have a UIViewController that is able to show its content via a UICollectionView (cv) or via a UITableView (tv). 我有一个UIViewController ,它可以通过UICollectionView (cv)或UITableView (tv)显示其内容。

Both views are added to the view hierarchy via storyboard and I'm just hiding the one that should not be shown. 这两个视图都通过情节提要添加到视图层次结构中,而我只是隐藏了不应显示的视图。 Both the UICollectionView and the UITableView have the same data source. UICollectionViewUITableView都具有相同的数据源。 The UICollectionView is showing the content in a two items per row grid, the UITableView obviously in a one item per row grid. UICollectionView以每行两个项目显示内容, UITableView显然以每行一个项目显示内容。

So what I want to happen is if the user decides to switch between the views the newly shown view should scroll to the element that was visible in the other view. 所以我想发生的是,如果用户决定在视图之间进行切换,则新显示的视图应滚动到另一个视图中可见的元素。

I did some experimenting with scrollToRowAtIndexPath:atScrollPosition:animated: and scrollToItemAtIndexPath:atScrollPosition:animated: with no success. 我做了一些对scrollToRowAtIndexPath:atScrollPosition:animated:scrollToItemAtIndexPath:atScrollPosition:animated: ,但没有成功。

I understand, that both the UICollectionView and UITableView are able to return their current visible items'/rows' indexPaths, but how can i transform those indexPath to a indexPath of the other view and tell them to scroll to that element? 我知道, UICollectionViewUITableView都能够返回其当前可见项的/行的indexPath,但是我如何才能将那些indexPath转换为另一个视图的indexPath并告诉它们滚动到该元素?

My current touch event handling of the switch button looks like this: 我当前对切换按钮的触摸事件处理如下所示:

 - (IBAction)switchView:(id)sender { self.showListView = !self.showListView; UIView *fromView, *toView; NSIndexPath *indexPath; if (self.showListView) { fromView = self.ArticleCollection; toView = self.ArticleList; CGRect visibleRect = (CGRect){.origin = self.ArticleCollection.contentOffset, .size = self.ArticleCollection.bounds.size}; CGPoint visiblePoint = CGPointMake(100, CGRectGetMidY(visibleRect)); indexPath = [self.ArticleCollection indexPathForItemAtPoint:visiblePoint]; } else { fromView = self.ArticleList; toView = self.ArticleCollection; CGRect visibleRect = (CGRect){.origin = self.ArticleList.contentOffset, .size = self.ArticleList.bounds.size}; CGPoint visiblePoint = CGPointMake(100, CGRectGetMidY(visibleRect)); indexPath = [self.ArticleList indexPathForRowAtPoint:visiblePoint]; } NSInteger row = indexPath.row; if (self.showListView) { [self.ArticleList scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:row*2 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; } else { [self.ArticleCollection scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:ceil(row/2) inSection:0 atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO]]; } // Here a transitionFromView:ToView:duration:options:completion call follows } 

Thanks in advance for any contribution to my problem. 在此先感谢您为我的问题所做的任何贡献。

Appart from a little typo inside the scrollToItemAtIndexPath:atScrollPosition:animated: call: Appart从scrollToItemAtIndexPath:atScrollPosition:animated内的一点错字呼叫:

[self.ArticleCollection scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:row
                                                                        inSection:0]
                                                                 atScrollPosition:UICollectionViewScrollPositionCenteredVertically
                                                                         animated:NO];

I did think indexPath.row would hold different values whether it came from the cv's visible indexPath or the tv's visible indexPath so I calculated the new row by multiplying or dividing through 2. But as it turns out the rows are identical in both cases, so I just needed to use the same value for both cases: 我确实认为indexPath.row会保留不同的值,无论它是来自cv的可见indexPath还是来自电视的可见indexPath,因此我通过乘以或除以2来计算新行。但是事实证明,在两种情况下,行都是相同的,因此在这两种情况下,我只需要使用相同的值即可:

NSInteger row = indexPath.row;

if (self.showListView) {
    [self.ArticleList scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0]
                            atScrollPosition:UITableViewScrollPositionTop
                                    animated:NO];
} else {
    [self.ArticleCollection scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:row
                                                                        inSection:0]
                                                                 atScrollPosition:UICollectionViewScrollPositionCenteredVertically
                                                                         animated:NO];
}

Sorry for the inconvenience. 抱歉给你带来不便。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM