6

3 本指のピンチを実装しようとすると、いくつかの問題が発生します。

個人的には2本指ローテーションで2本指ピンチを使ってきました!(同時のジェスチャーは必要ありません、または必要ありません)問題は、両方が非常に似ているため、多くの場合、システムが間違った動きを識別することです。そのため、システムに識別させるために、指を離してもう一度押す必要があります回転 (通常は最初にピンチを識別します)

delayBeginが役立つかどうか、または同時ジェスチャーをアクティブにすることができるかどうかをよく検索しましたが、どれもうまくいきませんでした。回転するより)。

問題は、ご存知のように、ピンチが 2 本の指でしか機能しないことです。そこで、 をサブクラス化し、UIPinchGestureReconizer画面上に 3 本の指がある場合にのみ機能させることにしました。残りは、標準のピンチが機能するように機能し、(スケールを計算するために)3 本目の指を無視しても機能しますが、3 本目の指がまだ画面上にあることを確認してください。

ThreeFingerPinchRecognizerだから私は私の(そのサブクラスはUIPinchGestureRecognizer)のために次の実装を試しました

@implementation GRThreeFingerPinchRecognizer

-(id)initWithTarget:(id)target action:(SEL)action
    {
    self = [super initWithTarget:target action:action];
    if(self){
    }
    return self;
}

- (void)reset
{
    [super reset];
}

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    int numberOfTouches = event.allTouches.count;
    if (numberOfTouches == 3) 
     {
        [super touchesBegan:touches withEvent:event];
     }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    int numberOfTouches = event.allTouches.count;
    if (numberOfTouches == 3)
    {
        [super touchesMoved:touches withEvent:event];
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{ 
        [super touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesCancelled:touches withEvent:event];
 }

ご覧のとおり、2 本指ピンチと同じ機能を取得しようとしています (関数を呼び出すだけ[super]で、touchesBeganおよびtouchesMoved関数で、画面上に 3 本の指があるかどうかをテストしています ( event.alltouches.count)

これで2本指での回転はバッチリ効くのですが、ピンチがあまり効かず、発動しにくく、発動しても2本指のピンチとしては機能しません…

私はこれを完全に間違っているかもしれないことを知っているので、どんな助けも素晴らしいでしょう!!

どうもありがとうございました!

4

1 に答える 1

0

ピンチの状態を識別するのに役立つこのスニペットを参照してください。

if (pinch.numberOfTouches > 1)
{
    CGPoint firstPoint = [pinch locationOfTouch:0 inView:self];
    CGPoint secPoint = [pinch locationOfTouch:1 inView:self];
    currentUpperY = MIN(firstPoint.y, secPoint.y);
    if (previousY == 0) previousY = currentUpperY;
    Float32 y = (self.contentOffset.y + previousY - currentUpperY);
    [self setContentOffset:CGPointMake(0, y < 0 ? 0 : y) animated:NO];

    if (pinch.state == UIGestureRecognizerStateBegan)
    {
        pinchStarted = YES;
        firstY = MIN(firstPoint.y, secPoint.y);
        secondY = MAX(firstPoint.y, secPoint.y);
        NSArray *pinchedIndexs = [self indexPathsForRowsInRect:CGRectMake(0.0, firstY, CGRectGetWidth(self.bounds), secondY)];
        if (pinchedIndexs.count) itemToOpenOrClose = [[currentItems subarrayWithRange:NSMakeRange(((NSIndexPath *)[pinchedIndexs objectAtIndex:0]).row, pinchedIndexs.count - 1)] copy];
    }
}

if ((pinch.state == UIGestureRecognizerStateChanged && pinchStarted && itemToOpenOrClose.count)
    || pinch.state == UIGestureRecognizerStateEnded)
{
    if (pinch.scale > 1) // Pinch OUT
    {
        for (Item *item in itemToOpenOrClose)
        {                
            [self openItem:item inIndexPath:[NSIndexPath indexPathForRow:[currentItems indexOfObject:item] inSection:0]];
        }
    }
    else if (pinch.scale < 1) // Pinch IN
    {
        for (Item *item in itemToOpenOrClose)
        {
            [self closeItem:item inIndexPath:[NSIndexPath indexPathForRow:[currentItems indexOfObject:item] inSection:0]];
        }
    }

    if (pinch.state == UIGestureRecognizerStateEnded)
    {
        pinchStarted = NO;
        itemToOpenOrClose = nil;
        previousY = 0;
    }
}
于 2013-03-07T07:49:29.290 に答える