4

2 つのビューの間に提供される分割ビューを使用して、ビューのサイズ変更機能を許可する必要がある iPad アプリを構築しています。分割ビューは、2 つのハーフスクリーン コンテンツ ビューの間の高さ 20 ピクセルのビューです。添付の​​画像を参照してください。

ユーザーがこの分割ビューを上下にスクロールすると、両方のコンテンツ ビューのサイズが適切に変更されます。デリゲートで以下に示すコードとしてデリゲートを使用して、これを拡張UIViewおよび実装しました。それは正常に動作します。唯一欠けているのは、分割ビューを直接上下にフリックできないことです。一番上または一番下までドラッグする必要があります。touchMovedtouchesMovedTouchMoved

ビューのフリックをサポートするために試しUIPanGestureRecognizerましたが、スムーズなドラッグが見られません。コードに示すように、親の分割位置を設定すると、両方のコンテンツ ビューのサイズが変更されます。状態で分割位置の変更を処理するときはUIGestureRecognizerStateChanged、分割ビューをタッチするだけで上または下にフリックします。分割位置の変更を処理UIGestureRecognizerStateEndedしても同じですが、dividerview のスクロールでコンテンツ ビューのサイズが変更されません。

コンテンツビューのサイズ変更(のようなtouchMoved)とビューのフリックを使用して、分割ビューのスムーズなスクロールの両方を実現するにはどうすればよいか教えてください。代替アプローチも問題ありません。ありがとう。

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    if (touch) {
        CGPoint lastPt = [touch previousLocationInView:self];
        CGPoint pt = [touch locationInView:self];
        float offset = pt.y - lastPt.y;
        self.parentViewController.splitPosition = self.parentViewController.splitPosition + offset;
    }
}

- (void)handlePan:(UIPanGestureRecognizer*)recognizer {

    CGPoint translation = [recognizer translationInView:recognizer.view];
    CGPoint velocity = [recognizer velocityInView:recognizer.view];

    if (recognizer.state == UIGestureRecognizerStateBegan) {
    } else if (recognizer.state == UIGestureRecognizerStateChanged) {
       // If I change split position here, I don't see smooth scrolling dividerview...it directly jumps to the top or bottom!
       self.parentViewController.splitPosition = self.parentViewController.splitPosition + translation.y;
    } else if (recognizer.state == UIGestureRecognizerStateEnded) {
      // If I change split position here, the same thing happens at end and I don't see my divider view moving with my scrolling and resizing my views.
        self.parentViewController.splitPosition = self.parentViewController.splitPosition + translation.y;
    }
}

初期画面

初期画面

分割ビューを下方向にスクロールして、トップ ビューのサイズを拡大しました。

分割ビューをスクロールしてトップ ビューのサイズを拡大

トップ ビューはここでは完全に非表示になっていますが、分割ビューを一番上までスクロールする必要があります。分割ビューをフリックして、任意の位置から直接上に移動したい

トップ ビューはここでは完全に非表示になっていますが、分割ビューを一番上までスクロールする必要があります。 分割ビューをフリックして、任意の位置から直接上に移動したい。

4

1 に答える 1

9

私の理解が正しければ、ここには 2 つの別個の問題があります。

1 つ目: GestureRecognizer を使用するときの「滑らかでない」ドラッグ。コードの問題は、GR がハンドル メソッドを呼び出すたびに翻訳を追加することです。移動は継続的に測定されるため、呼び出されるたびにより高い値が追加されます (つまり、最初の呼び出しでは分割位置に 10 が追加され、2 回目では 20、3 回目では 30 というように追加されます)。

これを解決するには、分割位置を更新した後に平行移動をゼロに設定する必要があります。

- (void)handlePan:(UIPanGestureRecognizer*)recognizer {

    CGPoint translation = [recognizer translationInView:recognizer.view];

    if (recognizer.state == UIGestureRecognizerStateChanged) {
       self.parentViewController.splitPosition = self.parentViewController.splitPosition + translation.y;
    } 
    [recognizer setTranslation:CGPointZero inView:recognizer.view];
}

2 番目: ユーザーが分割位置を上または下にフリックできるようにするには、UIGestureRecognizerStateEnded で速度を確認し、値を超えた場合は即座に分割位置を上または下に設定します。

ただし、UISwipeGestureRecognizer を使用する方が便利な場合があります。

- (void)handleSwipe:(UISwipeGestureRecognizer *)gr
{
    if (gr.direction == UISwipeGestureRecognizerDirectionUp){
        [self.parentViewController moveSplitViewToTop];
    }
    else if (gr.direction == UISwipeGestureRecognizerDirectionDown){
        [self.parentViewController moveSplitViewToBottom];
    }
}

この場合、次のように設定して、PanGR がトリガーされる前に SwipeGR が失敗するようにする必要があるかもしれません (確かではありません)。

[panGestureRecognizer requireGestureRecognizerToFail:swipeGestureRecognizer];

それが役に立ったことを願っています。

編集:あなたのコメントに関しては、周波数は速度を意味すると思います。PanGR のみを使用する場合は、上記のコードを sth に変更できます。このような:

- (void)handlePan:(UIPanGestureRecognizer*)recognizer {

    CGPoint translation = [recognizer translationInView:recognizer.view];
    CGPoint velocity = [recognizer velocityInView:recognizer.view];

    if (recognizer.state == UIGestureRecognizerStateChanged) {
       self.parentViewController.splitPosition = self.parentViewController.splitPosition + translation.y;
    } 
    else if (recognizer.state == UIGestureRecognizerStateEnded){
        if (velocity.y > someValue){
            [self.parentViewController moveSplitViewToBottom];
        }
        else if (velocity.y < someValue){
            [self.parentViewController moveSplitViewToTop];
        }
    }
    [recognizer setTranslation:CGPointZero inView:recognizer.view];
}

速度が署名されているかどうかはわかりません。署名されていない場合は、if ブロックで翻訳を再度確認する必要があります。

于 2012-10-21T19:04:55.890 に答える