Mam hierarchię widoków, która wygląda mniej więcej tak:
UIView (A)
UIView > UIImageView
UIView > UIView (B)
UIView > UIView (B) > Rounded Rect Button
UIView > UIView (B) > UIImageView
UIView > UIView (B) > UILabel
Do mojego UIView (B) dołączyłem rozpoznawanie gestów. Problem, z którym się zmagam, polega na tym, że nie otrzymuję żadnych akcji dla przycisku Rounded Rect Button, który znajduje się wewnątrz UIView (B). Rozpoznawanie gestów za jednym dotknięciem przechwytuje / zastępuje zdarzenie Touch Up Inside przycisku.
Jak mogę to zrobić? Pomyślałem, że hierarchia łańcucha responderów zapewni, że zdarzenie dotknięcia przycisku będzie miało pierwszeństwo i zostanie wywołane! Czego mi brakuje?
Oto powiązany kod:
#pragma mark -
#pragma mark View lifecycle (Gesture recognizer setup)
- (void)viewDidLoad {
[super viewDidLoad];
// double tap gesture recognizer
UITapGestureRecognizer *dtapGestureRecognize = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapGestureRecognizer:)];
dtapGestureRecognize.delegate = self;
dtapGestureRecognize.numberOfTapsRequired = 2;
[self.viewB addGestureRecognizer:dtapGestureRecognize];
// single tap gesture recognizer
UITapGestureRecognizer *tapGestureRecognize = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGestureRecognizer:)];
tapGestureRecognize.delegate = self;
tapGestureRecognize.numberOfTapsRequired = 1;
[tapGestureRecognize requireGestureRecognizerToFail:dtapGestureRecognize];
[self.viewB addGestureRecognizer:tapGestureRecognize];
// add gesture recodgnizer to the grid view to start the edit mode
UILongPressGestureRecognizer *pahGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGestureRecognizerStateChanged:)];
pahGestureRecognizer.delegate = self;
pahGestureRecognizer.minimumPressDuration = 0.5;
[self.viewB addGestureRecognizer:pahGestureRecognizer];
[dtapGestureRecognize release];
[tapGestureRecognize release];
[pahGestureRecognizer release];
}
#pragma mark -
#pragma mark Button actions
- (IBAction)buttonTouchUpInside:(id)sender {
NSLog(@"%s, %@", __FUNCTION__, sender);
}
#pragma mark -
#pragma mark Gesture recognizer actions
- (void)singleTapGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
NSLog(@"%s", __FUNCTION__);
}
- (void)doubleTapGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
NSLog(@"%s", __FUNCTION__);
}
- (void)longPressGestureRecognizerStateChanged:(UIGestureRecognizer *)gestureRecognizer {
switch (gestureRecognizer.state) {
case UIGestureRecognizerStateEnded: {
NSLog(@"%s", __FUNCTION__);
break;
}
default:
break;
}
}
Odpowiedzi:
W metodzie „shouldReceiveTouch” należy dodać warunek, który zwróci NIE, jeśli dotknięcie jest w przycisku.
To pochodzi z przykładu Apple SimpleGestureRecognizers .
mam nadzieję, że to pomoże
Edytować
Jak zauważył Daniel, musisz się dostosować, aby
UIGestureRecognizerDelegate
to zadziałało.shani
źródło
if ( [touch.view isKindOfClass:[UIControl class]] || [[touch.view superview] isKindOfClass:[UITableViewCell class]] ) {
... Zauważ, że komórki tableview są „dotykane” w ich contentView, który jest członkiem prywatnej klasy, więc zamiast tego sprawdzamy klasę superview.Miałem też ten sam problem, potem próbowałem
Teraz działa doskonale .........
źródło
myGestureRecognizer.delegate = self;
Ogólnie rzecz biorąc, używamy poniższej metody delegowania, aby uniknąć dotykania we wszelkiego rodzaju kontrolach UIC:
Uwaga: NIE WOLNO tego sprawdzać (sprawdź typ klasy rozpoznawania.view) gestRecognizerShouldBegin, nie zadziała.
źródło
Oto wersja Swift 3.0 :
Nie zapomnij:
Make your tapper object delegate to self (e.g: tapper.delegate = self)
źródło
Oto wersja Swift:
Nie zapomnij:
UIGestureRecognizerDelegate
tapper.delegate = self
)źródło
Moim zdaniem najlepszym rozwiązaniem jest użycie poniższego fragmentu kodu:
źródło