保持 UITableView 和 UICollectionView 滚动位置同步
Keeping UITableView and UICollectionView scroll position in sync
我有一个 UIViewController
可以通过 UICollectionView
(cv) 或 UITableView
(tv) 显示其内容。
两个视图都通过情节提要添加到视图层次结构中,我只是隐藏了不应显示的视图。 UICollectionView
和 UITableView
具有相同的数据源。
UICollectionView
在每行网格中显示内容,UITableView
显然在每行网格中显示内容。
所以我想要发生的是,如果用户决定在视图之间切换,新显示的视图应该滚动到在另一个视图中可见的元素。
我用 scrollToRowAtIndexPath:atScrollPosition:animated:
和 scrollToItemAtIndexPath:atScrollPosition:animated:
做了一些试验,但没有成功。
我明白,UICollectionView
和 UITableView
都能够 return 它们当前可见的项目/行的 indexPaths,但是我如何将这些 indexPath 转换为 indexPath另一个视图并告诉他们滚动到该元素?
我当前对开关按钮的触摸事件处理如下所示:
- (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
}
提前感谢您对我的问题的任何贡献。
来自 scrollToItemAtIndexPath:atScrollPosition:animated: 调用中的一个小错字:
[self.ArticleCollection scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:row
inSection:0]
atScrollPosition:UICollectionViewScrollPositionCenteredVertically
animated:NO];
我确实认为 indexPath.row 会包含不同的值,无论它来自 cv 的可见索引路径还是电视的可见索引路径,所以我通过乘法或除法计算了新行通过 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];
}
对于给您带来的不便,我们深表歉意。
我有一个 UIViewController
可以通过 UICollectionView
(cv) 或 UITableView
(tv) 显示其内容。
两个视图都通过情节提要添加到视图层次结构中,我只是隐藏了不应显示的视图。 UICollectionView
和 UITableView
具有相同的数据源。
UICollectionView
在每行网格中显示内容,UITableView
显然在每行网格中显示内容。
所以我想要发生的是,如果用户决定在视图之间切换,新显示的视图应该滚动到在另一个视图中可见的元素。
我用 scrollToRowAtIndexPath:atScrollPosition:animated:
和 scrollToItemAtIndexPath:atScrollPosition:animated:
做了一些试验,但没有成功。
我明白,UICollectionView
和 UITableView
都能够 return 它们当前可见的项目/行的 indexPaths,但是我如何将这些 indexPath 转换为 indexPath另一个视图并告诉他们滚动到该元素?
我当前对开关按钮的触摸事件处理如下所示:
- (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
}
提前感谢您对我的问题的任何贡献。
来自 scrollToItemAtIndexPath:atScrollPosition:animated: 调用中的一个小错字:
[self.ArticleCollection scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:row
inSection:0]
atScrollPosition:UICollectionViewScrollPositionCenteredVertically
animated:NO];
我确实认为 indexPath.row 会包含不同的值,无论它来自 cv 的可见索引路径还是电视的可见索引路径,所以我通过乘法或除法计算了新行通过 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];
}
对于给您带来的不便,我们深表歉意。