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];
    }
}

コレクションビューをスクロールすると、アニメーション化された(YES)パラメーターが原因で、テーブルビューのスクロールに時間がかかります。scrollToRowAtIndexPath: をアニメーションなしで使用すると、魅力的に機能します。しかし、アニメーション フラグを使用するとすぐに、(非常に論理的に) iOS が scrollToRowAtIndexPath をキューに入れ、一度に 1 回実行するように見え、アニメーションに遅れが生じます。

FWI、 alreadySelectedIndexPaths には、既にスクロールした indexPath のリストが含まれています (ただし、この文が明確かどうかはわかりません :D :D)

以前の注文をキャンセルする方法があるかどうかを調べましたが、cancelPreviousPerformRequestsWithTarget: with cancels the last performSelector 呼び出しを除いて、有用なものは見つかりませんでした。

ここでスムーズなアニメーションを取得する方法がわかりましたか?

助けてくれてありがとう。

4

2 に答える 2