[ios] UITapGestureRecognizer가있는 뷰 내부의 UIButton

와 함께 볼 수 있습니다 UITapGestureRecognizer. 뷰를 탭하면이 뷰 위에 다른 뷰가 나타납니다. 이 새로운 뷰에는 3 개의 버튼이 있습니다. 이제이 단추 중 하나를 누르면 단추 동작이 나타나지 않고 탭 동작 동작 만됩니다. 더 이상이 버튼을 사용할 수 없습니다. 이 버튼을 통해 이벤트를 진행하려면 어떻게해야합니까? 이상한 점은 버튼이 여전히 강조 표시된다는 것입니다.

탭을받은 후에 UITapGestureRecognizer를 제거 할 수 없습니다. 그것으로 새로운보기를 제거 할 수 있기 때문입니다. 전체 화면 보라 컨트롤과 같은 동작을 원한다는 의미 입니다.



답변

컨트롤러 또는보기 (제스쳐 인식기를 생성하는 것)를의 대리자로 설정할 수 있습니다 UITapGestureRecognizer. 그런 다음 대리자에서 구현할 수 있습니다 -gestureRecognizer:shouldReceiveTouch:. 구현에서 터치가 새로운 하위 뷰에 속하는지 테스트하고, 그렇다면 터치 인식기에 지시하도록 지시 할 수 있습니다. 다음과 같은 것 :

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    // test if our control subview is on-screen
    if (self.controlSubview.superview != nil) {
        if ([touch.view isDescendantOfView:self.controlSubview]) {
            // we touched our control surface
            return NO; // ignore the touch
        }
    }
    return YES; // handle the touch
}


답변

Casey의 후속 조치로 Kevin Ballard의 답변을 따르십시오.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
        if ([touch.view isKindOfClass:[UIControl class]]) {
            // we touched a button, slider, or other UIControl
            return NO; // ignore the touch
        }
    return YES; // handle the touch
}

이것은 기본적으로 버튼, 슬라이더 등과 같은 모든 사용자 입력 유형의 컨트롤을 작동시킵니다.


답변

이 답변을 여기에서 찾았습니다 : link

당신은 또한 사용할 수 있습니다

tapRecognizer.cancelsTouchesInView = NO;

탭 인식기가 모든 탭을 잡는 유일한 사람이되는 것을 방지합니다.

UPDATE – 마이클 이 속성을 설명하는 문서에 대한 링크를 언급 : cancelsTouchesInView


답변

Kevin Ballard의 답변에 대한 후속 조치로 동일한 문제가 발생 하여이 코드를 사용하게되었습니다.

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

동일한 효과가 있지만 모든 뷰 깊이에서 모든 UIButton에서 작동합니다 (UIButton은 여러 뷰 깊이였으며 UIGestureRecognizer의 대리자는 참조하지 않았습니다).


답변

iOS 6.0 이상에서 기본 제어 조치는 겹치는 제스처 인식기 동작을 방지합니다. 예를 들어, 버튼의 기본 동작은 단일 탭입니다. 버튼의 상위보기에 단일 탭 제스처 인식기가 연결되어 있고 사용자가 버튼을 누르면 버튼의 동작 방법은 제스처 인식기 대신 터치 이벤트를 수신합니다. 이것은 컨트롤의 기본 동작과 겹치는 제스처 인식에만 적용됩니다.

Apple의 API 문서에서


답변

이 답변은 불완전했습니다. 이 부울 연산을 사용하는 방법에 대한 여러 게시물을 읽어야했습니다.

* .h 파일에 이것을 추가하십시오

@interface v1ViewController : UIViewController <UIGestureRecognizerDelegate>

* .m 파일에 이것을 추가하십시오

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

    NSLog(@"went here ...");

    if ([touch.view isKindOfClass:[UIControl class]])
    {
        // we touched a button, slider, or other UIControl
        return NO; // ignore the touch
    }
    return YES; // handle the touch
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.



    //tap gestrure
    UITapGestureRecognizer *tapGestRecog = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(screenTappedOnce)];
    [tapGestRecog setNumberOfTapsRequired:1];
    [self.view addGestureRecognizer:tapGestRecog];


// This line is very important. if You don't add it then your boolean operation will never get called
tapGestRecog.delegate = self;

}


-(IBAction) screenTappedOnce
{
    NSLog(@"screenTappedOnce ...");

}


답변

여기에서 다른 방법을 찾았 습니다 . 각 버튼 내부의 터치 여부를 감지합니다.

(1) pointInside : withEvent :
(2) locationInView :

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
       shouldReceiveTouch:(UITouch *)touch {
    // Don't recognize taps in the buttons
    return (![self.button1 pointInside:[touch locationInView:self.button1] withEvent:nil] &&
            ![self.button2 pointInside:[touch locationInView:self.button2] withEvent:nil] &&
            ![self.button3 pointInside:[touch locationInView:self.button3] withEvent:nil]);
}