2013-05-17 8 views
9

Chcę uruchomić pewną metodę i powtarzać ją tak długo, jak długo ktoś jest wciśnięty na przycisk. Chcę, aby ta metoda przestała się powtarzać, gdy palec nie jest już na przycisku.UIButton naciśnij i przytrzymaj - powtarzaj czynność aż zwolnij

Czy istnieje sposób sprawdzenia, czy touchdown nadal występuje podczas wdrażania metody? Wsparcie!

+2

możliwe duplikat [sposób, aby UIButton ciągły ogień w sytuacji naciśnięcie i potrzymać?] (http://stackoverflow.com/questions/9 03114/droga do zrobienia-a-uibutton-ciągle-ogień-podczas-naciśnij-i-zatrzymajcie sytuację) – rmaddy

+0

w ten sposób zadziałało! Dziękuję Ci. Nie całkiem to rozumiałem, kiedy przeczytałem to przed opublikowaniem tego pytania - po raz drugi to urok. – dokun1

Odpowiedz

12

Można użyć zdarzenia sterującego UIControlEventTouchDown, aby uruchomić uruchamianą metodę, i UIControlEventTouchUpInside lub podobną, aby wykryć, kiedy przycisk nie jest już "wciskany".

Konfigurowanie działania przycisku, np:

[myButton addTarget:self action:@selector(startButtonTouch:) forControlEvents:UIControlEventTouchDown]; 
[myButton addTarget:self action:@selector(endButtonTouch:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside]; 

(. Uwaga dotyk powyżej spowoduje wewnątrz i na zewnątrz przycisk, aby wywołać metodę endButtonTouch:)

Następnie dodać startButtonTouch: i endButtonTouch metody, np:

- (void)startButtonTouch:(id)sender { 
    // start the process running... 
} 

- (void)endButtonTouch:(id)sender { 
// stop the running process... 
} 
+0

To podejście nie zadziała, jeśli użytkownik dotknie przycisku i przesunie palec poza granice przycisku. – danypata

+1

Użyj zarówno 'UIControlEventTouchUpInside' oraz' UIControlEventTouchUpOutside'. Dodano do odpowiedzi. Jeśli chcesz zakończyć, gdy użytkownik przeciągnie poza przycisk, dodaj również "UIControlEventTouchDragExit". – bobnoble

0

czerpiąc odpowiedzią bobnoble za oto widok pomocnika

#import <UIKit/UIKit.h> 

@interface YOIDCAutorepeatingButton : UIButton 

// you COULD pinch pennies switching to nonatomic, but consider 
// how much time it would take to debug if some day some moron decides without checking this spec 
// to alter this prop off another thread 
@property (atomic) NSTimeInterval delayUntilAutorepeatBegins; 
@property NSTimeInterval delayBetweenPresses; 

@property (weak) id<NSObject> recipient; 
@property SEL touchActionOnRecipient; 

@end 

-------------> .m

#import "YOIDCAutorepeatingButton.h" 

@interface YOIDCAutorepeatingButton() 
{ 
NSTimeInterval _pressStartedAt; 
} 

@end 

@implementation YOIDCAutorepeatingButton 


- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
self = [super initWithCoder:aDecoder]; 
if (self) { 
    [self addTarget:self action:@selector(startButtonTouch:) forControlEvents:UIControlEventTouchDown]; 
    [self addTarget:self action:@selector(endButtonTouch:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside]; 

    self.delayUntilAutorepeatBegins = .250; 
    self.delayBetweenPresses = .080; 
} 
return self; 
} 

-(void)killLastCharacter:(id)sender 
{ 
[self.recipient performSelector:self.touchActionOnRecipient withObject:sender]; 
} 

- (void)performAutorepeat:(id)sender 
{ 
if(!self.delayBetweenPresses) { 
    // bail 
    return; 
} 
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.delayBetweenPresses * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
    if(_pressStartedAt) { 
     [self killLastCharacter:sender]; 
     [self performAutorepeat:sender]; 
    } 
}); 
} 

- (void)startButtonTouch:(id)sender { 

[self killLastCharacter:sender]; 
NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate]; 
_pressStartedAt = now; 
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.delayUntilAutorepeatBegins * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
    if(_pressStartedAt) { 
     [self killLastCharacter:sender]; 
     [self performAutorepeat:sender]; 
    } 
}); 
} 

- (void)endButtonTouch:(id)sender { 
_pressStartedAt = 0; 
} 

@end 

-------- przykład użycia -------

- (IBAction)killLastDigit:(id)sender { 

.....

- (void)viewDidLoad 
{ 
assert(self.backSpace); 
[YOIDCAutorepeatingButton class]; // if xib is in a bundle other than main gottal load the class 
// otherwise you'd get -[UIButton setRecipient:]: unrecognized selector sent to instance 
// on setRecipient: 
self.backSpace.recipient = self; 
self.backSpace.touchActionOnRecipient = @selector(killLastDigit:); 
Powiązane problemy