8

私のallowableMovementプロパティはUILongPressGestureRecognizer無視されているようです。シングルビューアプリケーションテンプレートを使用して新しいプロジェクト(Xcode 4.5.1、iOS 6)を作成し、ビューにLong PressGestureRecognizerを追加しました。配線されたコンセントとアクションがあります。アクションメソッドのコードは次のとおりです。

- (IBAction)longPress:(UILongPressGestureRecognizer *)sender
{    
    if (sender.state == UIGestureRecognizerStatePossible)   NSLog(@"possible");
    if (sender.state == UIGestureRecognizerStateBegan)      NSLog(@"began");
    if (sender.state == UIGestureRecognizerStateChanged)    NSLog(@"changed");    
    if (sender.state == UIGestureRecognizerStateRecognized) NSLog(@"recognized");    
    if (sender.state == UIGestureRecognizerStateCancelled)  NSLog(@"cancelled");
    if (sender.state == UIGestureRecognizerStateFailed)     NSLog(@"failed");

    CGPoint locationInView = [sender locationInView:self.view];

    NSLog(@"long press: allowableMovement= %f, x= %f, y= %f", sender.allowableMovement, locationInView.x, locationInView.y);
}

十分に長く押して放すと、ログに次のように表示されます。

2012-10-30 20:24:41.449 Long Press[1078:907] began
2012-10-30 20:24:41.455 Long Press[1078:907] long press: allowableMovement= 10.000000, x= 210.500000, y= 99.500000
2012-10-30 20:24:42.880 Long Press[1078:907] recognized
2012-10-30 20:24:42.882 Long Press[1078:907] long press: allowableMovement= 10.000000, x= 208.500000, y= 96.000000

これは私が期待することです。

ただし、何に設定allowableMovementしても(ポジティブ、ネガティブ、ビッグ、スモール)、状態が1になるとUIGestureRecognizerStateBegan、画面全体に指をドラッグできます。状態がに変化しUIGestureRecognizerStateChanged、頻繁に更新され、locationInViewは引き続き正確に追跡します。手放すと、UIGestureRecognizerStateRecognized状態と最終出力がログに表示されます。

クラスリファレンスは、動きがを超えると認識機能が失敗するはずだと言っていallowableMovementます。allowableMovementプロパティが無視されているように見えるのはなぜですか?

4

2 に答える 2

29

プロパティは、ジェスチャが開始された後にドラッグできる距離に関するallowableMovementものではありません。ジェスチャーが始まる前にどれだけ移動できるかについてです。

クラスリファレンスから:

ジェスチャは、許容される指の数(numberOfTouchesRequired)が指定された期間(minimumPressDuration)押され、タッチが許容される移動範囲(allowableMovement)を超えて移動しない場合に開始されます(UIGestureRecognizerStateBegan)。

minimumPressDurationこれは、3秒などの高い値とallowableMovement、1ピクセルなどの低い値に設定すると明らかになります。指がまったく回転しない場合、ジェスチャーは開始されません。ただし、allowableMovement100に設定すると、指がかなり回転し、ジェスチャが開始されます。

このように、それは他のプロパティのようです。それらはすべて、ジェスチャーを開始するために必要なものに関するものです。

于 2012-10-31T14:13:22.660 に答える
6

allowableMovementまさにその目的があると思いました。で「期待される」動作を実装するために、小さなサブクラスを作成しましたallowableMovementAfterBegan

#import <UIKit/UIKit.h>
#import <UIKit/UIGestureRecognizerSubclass.h>

@interface TDMLongPressGestureRecognizer : UILongPressGestureRecognizer
@property (nonatomic, assign) CGFloat allowableMovementAfterBegan;
@end

@implementation TDMLongPressGestureRecognizer
{
    CGPoint initialPoint;
}

- (instancetype)initWithTarget:(id)target action:(SEL)action
{
    self = [super initWithTarget:target action:action];
    if (self) {
        // Use default value for allowableMovement before touches begin
        _allowableMovementAfterBegan = self.allowableMovement; 
    }
    return self;
}

- (void)reset
{
    [super reset];      
    initialPoint = CGPointZero;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];   
    initialPoint = [self locationInView:self.view];
}

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

    if (!CGPointEqualToPoint(initialPoint, CGPointZero))
    {
        CGPoint currentPoint = [self locationInView:self.view];

        CGFloat distance = hypot(initialPoint.x - currentPoint.x, initialPoint.y - currentPoint.y);
        if (distance > self.allowableMovementAfterBegan)
            self.state = UIGestureRecognizerStateFailed;
        }
    }
}
于 2014-01-13T22:28:19.580 に答える