2009-08-15 19 views
13

Jaki jest limit czasowy na dwukrotne dotknięcie dwóch dotknięć w systemie iPhone OS?Kliknij dwukrotnie lub dwa dotknięcia jednym kliknięciem?

// Edycja: Dlaczego jest to ważne?

Aby obsługiwać kliknięcie jednym dotknięciem i dwukrotne dotknięcie w inny sposób, przewodnik Apple mówi, aby wykonać performSelector...afterDelay z pewnym "rozsądnym" odstępem czasu przy pierwszym dotknięciu (i anulować go później, jeśli zostanie wykryte drugie naciśnięcie).

Problem polega na tym, że jeśli interwał jest zbyt krótki (0,1), działanie pojedynczego dotknięcia zostanie wykonane nawet po dwukrotnym dotknięciu (jeśli polega tylko na usłudze tapCount). Jeśli jest zbyt długi (0,8), użytkownik będzie czekał niepotrzebnie, aby jedno kliknięcie było rozpoznawane, gdy nie ma możliwości dwukrotnego dotknięcia.

To musi być dokładnie poprawna liczba, aby pracować optymalnie, ale zdecydowanie nie mniej, lub istnieje szansa na błędy (jednoczesne jednokrotne i dwukrotne dotknięcie).

+0

Możesz chcieć określić platformę, o którą pytasz. – retracile

+0

retracile, sprawdź tagi. – JoshJordan

+0

@retracile: na tym pytaniu znajduje się znacznik "iphone" (cóż, być może nie było tam 35 sekund temu, kiedy opublikowałeś swój komentarz); więc zgaduję, że jest na platformie iphone ;-) –

Odpowiedz

11

Możesz wykryć dowolną liczbę stuknięć gestem dotykowym. Nie trzeba też grać z NSTouches. Dla wszystkich użytkowników szukających rozwiązania tutaj jest.

Te proste linie kodu spełniają funkcję funkcji pojedynczego i podwójnego dotknięcia.

UITapGestureRecognizer *doubleTapRecg = [[UITapGestureRecognizer alloc] 
              initWithTarget:self 
              action:@selector(doubleTapped:)]; 
    doubleTapRecg.delegate = self; 
    doubleTapRecg.numberOfTapsRequired = 2; 
    doubleTapRecg.numberOfTouchesRequired = 1; 
    [view addGestureRecognizer:doubleTapRecg]; 


    UITapGestureRecognizer *tapRecg = [[UITapGestureRecognizer alloc] 
             initWithTarget:self 
             action:@selector(tapped:)]; 
    tapRecg.delegate = self; 
    tapRecg.numberOfTapsRequired = 1; 
    tapRecg.numberOfTouchesRequired = 1; 
    [view addGestureRecognizer:tapRecg]; 
    [tapRecg requireGestureRecognizerToFail:doubleTapRecg]; 


    [doubleTapRecg release]; 
    [tapRecg release]; 
+2

Zmieniam zaakceptowaną na to odpowiedź, ponieważ wydaje się, że jest to właściwy sposób, aby to zrobić w dzisiejszych czasach. Ale zanim skomentowałam poprzednią odpowiedź i wywoływałam inne odpowiedzi, pamiętaj, że zostały wysłane na 3 lata przed twoją i zanim UITapGestureRecognizer nawet istniał;) –

+0

to było moje inne konto: D – yunas

+0

Bez ręcznych zegarów lub opóźnień, które zmuszają cię do decydowania, ile msecs czekać, niesamowite! – cprcrack

1

Nie wierzę, że istnieje domyślny limit czasowy - to jest to, co "czuje" się dobrze, gdy go wypróbujesz. Apple ma przykład here, w którym nie określają również konkretnej godziny.

+0

Musi istnieć pewien limit, ponieważ wartość parametru UITouch nie zwiększa się, jeśli kliknięcia są od siebie oddalone o sekundę, ale występują, gdy są blisko siebie. –

5

na temat: Developer na developer.apple.com, deweloperem Apple powiedział:

  • Nie ma stały odstęp czasu, ale definicja całego systemu jest dzisiaj ukryte w nieruchomości tapCount z UITouch.
  • Nie ma wartości domyślnej dla tego opóźnienia i opóźnienia dotykowego i wstrzymania.
  • SpringBoard ma wartość zakodowaną na stałe.

Przekazałem to firmie Apple pod numerem bug 68405.

10
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 

    UITouch *touch = [touches anyObject]; 

    NSUInteger tapCount = [touch tapCount]; 

    switch (tapCount) { 
     case 1: 
      [self performSelector:@selector(singleTapMethod) withObject:nil afterDelay:.4]; 
      break; 
     case 2: 
      [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(singleTapMethod) object:nil]; 
      [self performSelector:@selector(doubleTapMethod) withObject:nil afterDelay:.4]; 
      break; 
     case 3: 
      [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(doubleTapMethod) object:nil]; 
      [self performSelector:@selector(tripleTapMethod) withObject:nil afterDelay:.4]; 
      break; 
     case 4: 
      [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(tripleTapMethod) object:nil]; 
      [self quadrupleTap]; 
      break; 
     default: 
      break; 
    } 

} 
@end 

dla mnie ten kod działa perfekcyjnie dobrze .... :) ostatni post był 15 sierpnia około 09 .... ale szło przez tego samego problemu tak myślał dzielić rozwiązanie znalazłem ....

0

nie jestem pewien, czy jest to poprawny sposób robienia rzeczy, ale ten kod działa dobrze dla mnie.

w moim pliku .h:

@interface MyViewController : UIViewController { 

int tapCount; 

} 
@property (nonatomic, assign)int tapCount; 
@end 

w moim pliku .m:

@synthesize tapCount; 

- (void)tapGesture:(UIGestureRecognizer*)gesture { 
    tapCount = tapCount + 1; 
    [self performSelector:@selector(correctTapCount) withObject:nil afterDelay:0.3]; 


} 
-(void)correctTapCount { 
    if (tapCount == 1) { 
     NSLog(@"Single Tap"); 
    } 
    if (tapCount == 2) { 
     NSLog(@"Double Tap"); 
    } 

    //reset TapCount 
    tapCount = 0; 
} 

i to, gdzie mogę dodać moje kranu słuchacza (jest na UIImageView)

//add tap listener 
carImage.userInteractionEnabled = YES; 
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)]; 
[carImage addGestureRecognizer:tap]; 
[tap release]; 

Powodzenia i szczęśliwego kodowania!

Powiązane problemy