2012-10-30 7 views
6

allowableMovement मेरे UILongPressGestureRecognizer में संपत्ति को अनदेखा किया जा रहा है। मैंने सिंगल व्यू एप्लिकेशन टेम्पलेट का उपयोग करके एक नई परियोजना (एक्सकोड 4.5.1, आईओएस 6) बनाई और दृश्य में एक लांग प्रेस जेस्चर रिकॉग्नाइज़र जोड़ा। एक आउटलेट वायर्ड और एक एक्शन है। यहाँ कार्रवाई विधि के लिए कोड है:स्वीकार्य प्रतीत होता है

- (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 (सकारात्मक, नकारात्मक, बड़ा, छोटा) सेट किया है, एक बार राज्य UIGestureRecognizerStateBegan है, मैं अपनी स्क्रीन को पूरी स्क्रीन पर खींच सकता हूं। राज्य UIGestureRecognizerStateChanged में बदलता है और अक्सर अपडेट और स्थान होते हैं इनव्यू सटीक रूप से ट्रैक करना जारी रखता है। जब मैं जाने देता हूं तो मुझे UIGestureRecognizerStateRecognized राज्य और लॉग के लिए अंतिम आउटपुट मिलता है।

कक्षा संदर्भ कहता है कि यदि आंदोलन allowableMovement से अधिक हो तो पहचानकर्ता विफल होना चाहिए। allowableMovement संपत्ति को अनदेखा क्यों किया जाता है?

उत्तर

23

allowableMovement संपत्ति इस बात के बारे में नहीं है कि आप इशारा शुरू होने के बाद कितनी दूर खींच सकते हैं। इशारा शुरू होने से पहले आप कितनी दूर जा सकते हैं।

वर्ग संदर्भ से:

इशारा शुरू होता है (UIGestureRecognizerStateBegan) जब स्वीकार्य उंगलियों की संख्या (numberOfTouchesRequired) निर्दिष्ट अवधि (minimumPressDuration) के लिए दबाया गया है और अंतिम रूप से स्वीकार्य सीमा से परे हिलना मत आंदोलन (स्वीकार्य सुधार)।

यह जब आप कुछ उच्च की तरह 3 सेकंड और allowableMovement कम की तरह 1 पिक्सेल कुछ करने के लिए minimumPressDuration सेट स्पष्ट हो जाता है। यदि आपकी उंगली सभी इशारा पर रोल शुरू नहीं होगी। लेकिन अगर आप allowableMovement से 100 सेट करते हैं तो आपकी उंगली काफी हद तक रोल हो सकती है और इशारा शुरू हो जाएगा।

इस तरह यह अन्य गुणों की तरह है। वे सभी इस बारे में हैं कि इशारा शुरू करने के लिए क्या आवश्यक है।

+0

@ मुरे सगल: इससे मेरा भ्रम भी हल हो गया। आश्चर्य कीजिए, अगर यह पता लगाने का कोई तरीका है कि क्या LongPressGesture शुरू होने के बाद उपयोगकर्ता अपनी अंगुली को दृश्य से बाहर खींचता है। – Kashif

+0

@TPos मुझे लगता है कि आप 'locationInView:' या इस तरह के तरीकों में से एक का उपयोग कर सकते हैं। लेकिन ऐसा लगता है कि यह अपने स्वयं के प्रश्न के योग्य होगा। –

4

मैंने सोचा कि 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; 
     } 
    } 
} 
+0

दिलचस्प। स्वीकार्य आंदोलन को सीमित करने के लिए आपका उपयोग केस क्या है? –

+0

मैंने इसे UIScrollView में सामग्री पर लंबे समय तक दबाए जाने के लिए उपयोग किया है। – duemunk

+0

बस उस मामले में भाग गया जहां आप इसका जिक्र कर रहे हैं - एक UICollectionViewCell है कि मैं एक इशारा पहचानकर्ता जोड़ना चाहता हूं, लेकिन अगर उपयोगकर्ता UICollectionView को लंबवत स्क्रॉल करता है तो इशारा रद्द करें (इस प्रकार UITableView डिफ़ॉल्ट रूप से काम करता है)। यह भी आश्चर्यजनक था कि स्वीकार्य स्मृति का मतलब यह भी नहीं था, लेकिन यह एक महान समाधान की तरह लगता है तो धन्यवाद! –