2011-01-28 22 views
94

Tôi có phân cấp hình ảnh trông giống như thế này:Gesture recognizer và nút hành động

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

Tôi đã kèm theo cử chỉ recognizer (s) để UIView của tôi (B). Các vấn đề mà tôi đang phải đối mặt là tôi không nhận được bất kỳ hành động cho các nút tròn tròn mà là bên trong UIView (B). Trình nhận dạng cử chỉ singleTap nắm bắt/ghi đè sự kiện Touch Up Inside của nút.

Tôi làm cách nào để hoạt động? Tôi nghĩ rằng hệ thống phân cấp chuỗi trả lời sẽ đảm bảo rằng sự kiện chạm nút sẽ được ưu tiên, và nó S get được kích hoạt! Tôi đang thiếu gì?

Dưới đây là một số mã có liên quan:

#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; 
    } 
} 
+0

Cách đơn giản nhất là để thiết lập cancelsTouchesInView = false –

Trả lời

165

Trong phương thức "shouldReceiveTouch" bạn nên thêm một điều kiện rằng sẽ trở lại NO nếu các liên lạc là trong nút.

Đây là ví dụ từ quả táo SimpleGestureRecognizers ví dụ.

- (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; 
} 

hy vọng nó sẽ giúp

Sửa

Như Daniel lưu ý bạn phải phù hợp với UIGestureRecognizerDelegate cho nó để làm việc.

Shani

+1

Ah !!! Có, tôi đã quên về phương thức này -quyền nhận dạng: phương thức shouldReceiveTouch:. Cám ơn đã chỉ tôi hướng đi đúng. Mặc dù điều này giải quyết được vấn đề của tôi, nhưng tôi vẫn không biết tại sao hệ thống phân cấp trả lời lại không hoạt động trong trường hợp này. Nó có lẽ nên, nhưng nó không được xử lý bởi Apple. – Mustafa

+2

Hành vi nhận dạng UIGestureRecognizer được mô tả rõ ràng là tách biệt với chuỗi phản hồi "bình thường". Đây là quyết định thiết kế của Apple. –

+9

Hãy nhớ tuân thủ Giao thức UIGestureRecognizerDelegate và đặt đại biểu của UIGestureRecognizer cho đối tượng đó. – Daniel

48

Tôi cũng có cùng một vấn đề, sau đó tôi đã cố gắng với

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

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

Nó đang làm việc tại một cách hoàn hảo .........

+2

tôi chỉ bỏ lỡ 'myGestureRecognizer.delegate = self;' – zero3nna

18

Nói chung, chúng tôi sử dụng bên dưới phương thức ủy quyền để tránh liên lạc trong tất cả các loại UIControls:

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

Lưu ý: KHÔNG thực hiện việc kiểm tra này (c heck loại lớp recognizer.view) gestureRecognizerShouldBegin, nó sẽ không hoạt động.

4

Giải pháp tốt nhất là để tâm trí của tôi sử dụng đoạn mã dưới đây:

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

Đây là một phiên bản Swift:

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

Đừng quên:

  1. Làm cho bạn lớp học phù hợp với UIGestureRecognizerDelegate
  2. Làm cho đối tượng tapper của bạn de legate to self (ví dụ: tapper.delegate = self)
6

Đây là Swift 3.0 phiên bản:

extension UIViewController: UIGestureRecognizerDelegate { 

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

Đừng quên:

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

Các vấn đề liên quan