1

我有一个带有 collectionView (单条水平线)和下面的 tableview 的视图。两个视图在滚动时同步,因为它们以不同的方式显示相同的数据。事实上,如果你有这个应用程序,它就像“神奇”的应用程序。

我设法使用 UIScrollView Delegate 方法同步两个视图

#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, alreadySelectedIndexPaths 包含我已经滚动到的 indexPath 列表(我不知道这句话是否很清楚:D :D)

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

你看到我怎样才能在这里获得流畅的动画吗?

感谢您的帮助。

4

2 回答 2

4

每当滚动 tableView 或 collectionView 时覆盖 scrollviewDidScroll 方法。

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

然后你可以在另一个视图上设置这个偏移量。

您不需要对偏移量或任何东西进行动画处理,因为无论如何都会在动画循环中调用委托方法,因此只需设置偏移量就可以让它看起来像两个视图都被动画化了。

希望这可以帮助。

于 2013-06-10T10:26:27.097 回答
2

我有一个类似的问题。对我有用的是以下内容:

  1. 创建 UITableView 和 UICollectionView 的自定义子类
  2. 这两个子类都应该符合UIGestureRecognizer委托
  3. 在这两个类中都覆盖了gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)方法
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
  1. 您的表格视图和集合视图需要具有相同的超级视图。将两个手势识别器添加到您的超级视图
yourSuperview.addGestureRecognizer(scrollView.panGestureRecognizer)
yourSuperview.addGestureRecognizer(tableView.panGestureRecognizer)

希望这可以帮助!

于 2019-08-01T11:42:13.583 回答