Ios 在UITableView和UICollectionView之间同步滚动:使用多个ScrollToRowatineXpath时滞后

Ios 在UITableView和UICollectionView之间同步滚动:使用多个ScrollToRowatineXpath时滞后,ios,uitableview,uiscrollview,scroll,uicollectionview,Ios,Uitableview,Uiscrollview,Scroll,Uicollectionview,我有一个带有collectionView单条水平线的视图,下面有一个tableview。两个视图在滚动时同步,因为它们以不同的方式显示相同的数据。事实上,如果你有这个应用程序,它就像一个梦幻般的应用程序 我使用UIScrollView委托方法成功地同步了这两个视图 #pragma mark - UIScrollViewDelegate - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGPoint currentOffse

我有一个带有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时,tableview需要一些时间来滚动,这是因为设置了动画的YES参数。如果我使用ScrollToRowatineXpath:没有动画,它就像一个符咒。但是,只要我使用动画标志,iOS就会将ScrollToRowatineXpath排队,并一次运行一次,从而导致动画延迟

FWI,alreadySelectedIndexPaths包含一个我已经滚动到的indexPath列表,但我不知道这句话是否很清楚:D:D

我查看了是否有办法取消上一个订单,但除了cancelPreviousPerformRequestsWithTarget:with cancels上一个performSelector调用之外,它没有发现任何有用的东西

你看到了吗?我如何在这里获得平滑的动画


谢谢你的帮助

每当滚动tableView或collectionView时,重写scrollviewDidScroll方法

在这里,您可以获取正在滚动的视图的偏移量,并将其转换为另一个视图的偏移量

然后可以在另一个视图上设置此偏移

当代理方法在动画循环中被调用时,您不需要设置偏移或其他任何动画,因此仅设置偏移将使它看起来像两个视图都在设置动画


希望这有帮助。

每当滚动tableView或collectionView时,都会覆盖scrollviewDidScroll方法

在这里,您可以获取正在滚动的视图的偏移量,并将其转换为另一个视图的偏移量

然后可以在另一个视图上设置此偏移

当代理方法在动画循环中被调用时,您不需要设置偏移或其他任何动画,因此仅设置偏移将使它看起来像两个视图都在设置动画


希望这有帮助。

我也有类似的问题。对我起作用的是:

创建UITableView和UICollectionView的自定义子类 这两个子类都应该符合UIgestureRecognitor委托 在这两个类中,使用:方法同时重写GestureRecognitor_u3;:shouldRecognitizeWith:方法 公共功能手势识别器\手势识别器:UIGestureRecognizer,应与其他手势识别器同时识别:UIGestureRecognizer->Bool{ 返回真值 } 表视图和集合视图需要具有相同的superview。将两个手势识别器添加到superview yourSuperview.AddgestureRecognitzerScrollView.PangestureRecognitzer yourSuperview.AddgestureRecognitizerTableView.PangestureRecognitizer
希望这有帮助

我也有类似的问题。对我起作用的是:

创建UITableView和UICollectionView的自定义子类 这两个子类都应该符合UIgestureRecognitor委托 在这两个类中,使用:方法同时重写GestureRecognitor_u3;:shouldRecognitizeWith:方法 公共功能手势识别器\手势识别器:UIGestureRecognizer,应与其他手势识别器同时识别:UIGestureRecognizer->Bool{ 返回真值 } 表视图和集合视图需要具有相同的superview。将两个手势识别器添加到superview yourSuperview.AddgestureRecognitzerScrollView.PangestureRecognitzer yourSuperview.AddgestureRecognitizerTableView.PangestureRecognitizer
希望这有帮助

为什么不调用滚动视图代理?使用它们很容易做到这一点。代理被调用,但不是连续调用。当用户用手指滚动时,scrollViewDidScroll似乎只被调用一次,但之后不会被调用。还有ScrollViewWillendDraging:由于存在targetOffset,因此可以使用它,但计算每个视图的减速会有点困难:-/scrollViewDidScroll在滚动视图的任何移动过程中都会重复调用。无论用户是在滚动还是在减速,它都会被调用。@当你说“同步”时,我知道tableview和collectionview会同时滚动。然而,updateUIFromTimer:方法中的代码中的开关大小写则表明并非如此。为什么不删除开关并调用表和集合上的更新?此外,UITableView和UICollectionView都继承自UIScrollView,因此您可以使用setContentOffset:animated:method(带动画或不带动画)以编程方式滚动两者。@Fogmeister:我使用一个带有tableview的简单项目进行了检查,scrollviewdidscroll确实被连续调用。但它不在我的应用程序中,

很奇怪。。。我来看看…为什么不调用滚动视图代理?使用它们很容易做到这一点。代理被调用,但不是连续调用。当用户用手指滚动时,scrollViewDidScroll似乎只被调用一次,但之后不会被调用。还有ScrollViewWillendDraging:由于存在targetOffset,因此可以使用它,但计算每个视图的减速会有点困难:-/scrollViewDidScroll在滚动视图的任何移动过程中都会重复调用。无论用户是在滚动还是在减速,它都会被调用。@当你说“同步”时,我知道tableview和collectionview会同时滚动。然而,updateUIFromTimer:方法中的代码中的开关大小写则表明并非如此。为什么不删除开关并调用表和集合上的更新?此外,UITableView和UICollectionView都继承自UIScrollView,因此您可以使用setContentOffset:animated:method(带动画或不带动画)以编程方式滚动两者。@Fogmeister:我使用一个带有tableview的简单项目进行了检查,scrollviewdidscroll确实被连续调用。但它不在我的应用程序中,非常奇怪。。。我会查出来的…不用担心,很乐意帮忙:-嘿,老兄!我们尝试过这样做,但在将collectionView中使用的偏移量应用于滚动视图时,似乎没有同步,您知道是否需要进行某种转换吗?@RoiMulia您不应该这样做。不同步是什么意思?集合视图是一个滚动视图。因此,内容偏移量将是相同的。你看到了什么不同?也许可以在代码中添加一个新问题,等等。。。然后链接它。我来看看:-我会和我的团队一起努力解决这个问题。如果我们不能成功,我将发布一个问题!谢谢:不用担心,很乐意帮忙:-嘿,老兄!我们尝试过这样做,但在将collectionView中使用的偏移量应用于滚动视图时,似乎没有同步,您知道是否需要进行某种转换吗?@RoiMulia您不应该这样做。不同步是什么意思?集合视图是一个滚动视图。因此,内容偏移量将是相同的。你看到了什么不同?也许可以在代码中添加一个新问题,等等。。。然后链接它。我来看看:-我会和我的团队一起努力解决这个问题。如果我们不能成功,我将发布一个问题!谢谢您: