Распознаватель жестов и действия кнопок



у меня есть иерархия представлений, которая выглядит примерно так:



UIView (A)
UIView > UIImageView
UIView > UIView (B)
UIView > UIView (B) > Rounded Rect Button
UIView > UIView (B) > UIImageView
UIView > UIView (B) > UILabel


я прикрепил распознаватель жестов к моему UIView (B). Проблема, с которой я сталкиваюсь, заключается в том, что я не получаю никаких действий для округлой кнопки Rect, которая находится внутри UIView (B). Распознаватель жестов singleTap захватывает / переопределяет событие касания кнопки внутри.



Как я могу заставить его работать? Я думал, что иерархия цепочек ответчиков гарантирует, что событие касания кнопки будет отдав предпочтение, и он будет срабатывать! Чего мне не хватает?



вот код:



#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;
}
}
633   6  

6 ответов:

в методе "shouldReceiveTouch" вы должны добавить условие, которое будет возвращать NO, если касание находится в кнопке.

это от apple SimpleGestureRecognizers пример.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {

    // Disallow recognition of tap gestures in the segmented control.
    if ((touch.view == yourButton)) {//change it to your condition
        return NO;
    }
    return YES;
}

надеюсь, что это поможет

Edit

Как отметил Даниэль, вы должны соответствовать UIGestureRecognizerDelegate для его работы.

Шани

У меня тоже была такая же проблема, тогда я попробовал с

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{

    if ([touch.view isKindOfClass:[UIButton class]]) {      //change it to your condition
        return NO;
    }
    return YES;
}

теперь он работает отлично.........

вообще говоря, мы используем ниже делегат метод, чтобы избежать прикосновения во всех видах UIControls:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if (([touch.view isKindOfClass:[UIControl class]])) {
         return NO;
    }
    return YES;
}

Примечание: не делайте эту проверку (проверьте распознаватель.вид типа класса) gestureRecognizerShouldBegin, это не будет работать.

здесь Swift 3.0 версия:

extension UIViewController: UIGestureRecognizerDelegate {

public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    if touch.view is UIButton {
        return false
    }
    return true
}

Не забывайте:

Make your tapper object delegate to self (e.g: tapper.delegate = self)

вот быстрая версия:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    if (touch.view!.isKindOfClass(UIButton)) {
        return false
    }
    return true
}

не забывайте:

  1. сделать вас класс соответствует UIGestureRecognizerDelegate
  2. сделайте свой объект tapper делегировать себе (например:tapper.delegate = self)

самое лучшее решение-на мой взгляд, используя код ниже:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    CGPoint touchLocation = [touch locationInView:self.view];
    return !CGRectContainsPoint(self.menuButton.frame, touchLocation);
}

Comments

    Ничего не найдено.