【发布时间】:2013-06-05 19:57:01
【问题描述】:
我有一个带有collectionView(单条水平线)和下面的tableview 的视图。两个视图在滚动时同步,因为它们以不同的方式显示相同的数据。事实上,如果你有这个应用程序,它就像“神奇”的应用程序。
我设法使用 UIScrollView 委托方法同步两个视图
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGPoint currentOffset = scrollView.contentOffset;
NSLog(@"scrollViewDidScroll %@ - %@", NSStringFromCGPoint(scrollView.contentOffset), NSStringFromCGPoint(self.previousScrollOffset));
switch (self.scrollAnimation) {
case ScrollAnimationFromCollection:
{
if (currentOffset.x > self.previousScrollOffset.x && (self.scrollDirection == ScrollDirectionLeft || self.scrollDirection == ScrollDirectionNone))
{
// NSLog(@"Change to Right!");
self.scrollDirection = ScrollDirectionRight;
[self.alreadySelectedIndexPaths removeAllObjects];
}
else if (currentOffset.x <= self.previousScrollOffset.x && (self.scrollDirection == ScrollDirectionRight || self.scrollDirection == ScrollDirectionNone))
{
// NSLog(@"Change to Left!");
self.scrollDirection = ScrollDirectionLeft;
[self.alreadySelectedIndexPaths removeAllObjects];
}
[self moveTableView];
break;
}
case ScrollAnimationFromTableView:
{
if (currentOffset.y - self.previousScrollOffset.y > 0 && self.scrollDirection == ScrollDirectionBottom)
{
self.scrollDirection = ScrollDirectionTop;
[self.alreadySelectedIndexPaths removeAllObjects];
}
else if (currentOffset.y - self.previousScrollOffset.y <= 0 && self.scrollDirection == ScrollDirectionTop)
{
self.scrollDirection = ScrollDirectionBottom;
[self.alreadySelectedIndexPaths removeAllObjects];
}
[self moveCollectionView];
break;
}
default:
break;
}
self.previousScrollOffset = currentOffset;
}
#pragma mark - Move actions
- (void)moveCollectionView
{
NSIndexPath* currentIp = [[self.tableView indexPathsForVisibleRows] objectAtIndex:1];
NSLog(@"currentIp %@", currentIp);
if (![self.alreadySelectedIndexPaths containsObject:currentIp])
{
NSLog(@"Scroll to IndexPath centered!");
[self.alreadySelectedIndexPaths addObject:currentIp];
[self.collectionViewController.collectionView scrollToItemAtIndexPath:currentIp atScrollPosition:PSTCollectionViewScrollPositionCenteredHorizontally animated:YES];
}
}
- (void)moveTableView
{
NSIndexPath* currentIp = [self.collectionViewController.collectionView indexPathForItemAtPoint:[self.horizontalContainer convertPoint:self.horizontalContainer.center toView:self.collectionViewController.collectionView]];
NSLog(@"currentIp %@", currentIp);
if (![self.alreadySelectedIndexPaths containsObject:currentIp])
{
NSLog(@"Scroll to IndexPath At Top!");
[self.alreadySelectedIndexPaths addObject:currentIp];
self.tableView.decelerationRate = UIScrollViewDecelerationRateFast;
[self.tableView scrollToRowAtIndexPath:currentIp atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
}
它工作得非常好,除了一件事:当我滚动 collectionview 时,由于动画 (YES) 参数,tableview 需要一些时间来滚动。如果我使用 scrollToRowAtIndexPath: 没有动画,它就像一个魅力。但是,一旦我使用动画标志,iOS 似乎(非常合乎逻辑地)将 scrollToRowAtIndexPath 排队并一次运行一次,导致动画滞后。
FWI,hassSelectedIndexPaths 包含一个我已经滚动到的 indexPath 列表(我不知道这句话是否很清楚:D :D)
我查看是否有办法取消之前的订单,但除了 cancelPreviousPerformRequestsWithTarget: with 取消最后一次 performSelector 调用,它没有发现任何有用的东西。
你知道我怎样才能在这里获得流畅的动画吗?
感谢您的帮助。
【问题讨论】:
-
为什么不调用滚动视图代理?使用它们很容易做到这一点。
-
代理正在被呼叫,但不是连续呼叫。当用户用手指滚动时,似乎只调用了一次 scrollViewDidScroll ,但在那之后就没有了。还有一个 scrollViewWillEndDragging: 可以使用,因为有一个 targetOffset,但是计算每个视图的减速会有点棘手:-/
-
scrollViewDidScroll 在滚动视图的任何移动过程中被重复调用。无论用户是滚动还是减速都会调用它。
-
@Khal 当您说“同步”时,我了解 tableview 和 collectionview 将同时滚动。但是,
switch方法中updateUIFromTimer:方法中的代码中的情况表明并非如此。为什么不删除表和集合上的开关并调用更新?此外,UITableView和UICollectionView都继承自UIScrollView,因此您可以使用setContentOffset:animated:方法(带或不带动画)以编程方式滚动两者。 -
@Fogmeister :我检查了一个带有 tableview 的简单项目,scrollviewdidscroll 确实被连续调用。但它不在我的应用程序中,很奇怪......我去看看......
标签: ios uitableview uiscrollview scroll uicollectionview