Ios 保持UITableView和UICollectionView滚动位置同步

Ios 保持UITableView和UICollectionView滚动位置同步,ios,objective-c,iphone,uitableview,uicollectionview,Ios,Objective C,Iphone,Uitableview,Uicollectionview,我有一个UIViewController,可以通过UICollectionView(cv)或UITableView(tv)显示其内容 这两个视图都是通过情节提要添加到视图层次结构中的,我只是隐藏了一个不应该显示的视图。UICollectionView和UITableView都有相同的数据源。 UICollectionView以每行两项网格的形式显示内容,UITableView显然以每行一项网格的形式显示内容 所以我想做的是,如果用户决定在视图之间切换,新显示的视图应该滚动到在另一个视图中可见的元

我有一个
UIViewController
,可以通过
UICollectionView
(cv)或
UITableView
(tv)显示其内容

这两个视图都是通过情节提要添加到视图层次结构中的,我只是隐藏了一个不应该显示的视图。
UICollectionView
UITableView
都有相同的数据源。
UICollectionView
以每行两项网格的形式显示内容,
UITableView
显然以每行一项网格的形式显示内容

所以我想做的是,如果用户决定在视图之间切换,新显示的视图应该滚动到在另一个视图中可见的元素

我用
ScrollToRowatineXpath:atScrollPosition:animated:
ScrollToItemAtScrollPosition:animated:
做了一些实验,但没有成功

我知道,
UICollectionView
UITableView
都能够返回其当前可见项的/rows'indexPath,但是我如何将这些indexPath转换为另一个视图的indexPath,并告诉它们滚动到该元素

我当前对开关按钮的触摸事件处理如下所示:

-(iAction)开关视图:(id)发送方{
self.showListView=!self.showListView;
UIView*从视图,*到视图;
nsindepath*indepath;
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];
}
其他的
{
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行=indexPath.row;
if(self.showListView){
[self.ArticleList ScrollToRowatineXpath:[NSIndexPath indexPathForRow:row*2第1行:0]
atScrollPosition:UITableViewScrollPositionTop
动画:否];
}否则{
[self.ArticleCollection scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:ceil(第/2行)
位置:0
atScrollPosition:UICollectionViewScrollPositionCenter垂直
动画:否]];
}
//下面是从View:ToView:duration:options:completion调用的转换

}
从scrollToItemAtIndexPath:atScrollPosition:animated:call:

我确实认为indexPath.row将包含不同的值,无论它来自cv的visible Indexath还是tv的visible Indexath,因此我通过乘以或除以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];
}

很抱歉给您带来不便。

您为什么不简单地使用
UICollectionView
并切换流布局以在单栏和双栏模式之间切换?问得好。我还没有想到这个解决方案。但我猜布局切换会导致单单元格布局中断,因为cv显示的图像下面有文本,而tv显示的图像在左侧,文本在右侧。您也可以创建不同的集合视图单元格布局,当您切换模式时,您会提供不同的单元格布局。如果您按照我所说的做建议您也免费获得自动流布局切换动画:)好吧,这听起来是优化我当前实现的一个很好的解决方案。我至少会试试你的方法。谢谢你的意见!
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];
}