UITapGesture Recognizer가 있는 뷰 내부의 UIButton
나는 볼 수 있습니다.UITapGestureRecognizer
보기를 누르면 이 보기 위에 다른 보기가 나타납니다.이 새 보기에는 세 개의 단추가 있습니다.이 단추 중 하나를 누르면 단추 동작이 나타나지 않고 탭 동작만 나타납니다.그래서 저는 이 버튼들을 더 이상 사용할 수 없습니다.이 버튼으로 이벤트를 전달하려면 어떻게 해야 합니까?이상한 것은 버튼이 여전히 강조 표시된다는 것입니다.
UITapGesture Recognizer는 탭을 받은 후에만 제거할 수 없습니다.새 보기를 제거할 수도 있기 때문입니다.즉, 전체 화면 비디오 컨트롤과 같은 동작을 원합니다.
컨트롤러 또는 보기(동작 인식기를 생성하는 컨트롤러 또는 보기)를 의 대리자로 설정할 수 있습니다.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
}
Kevin Ballard의 답변에 대한 Casey의 후속 조치로서:
- (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
}
이것은 기본적으로 버튼, 슬라이더 등과 같은 모든 사용자 입력 유형의 컨트롤을 작동시킵니다.
다음 답변을 찾았습니다: 링크
사용할 수도 있습니다.
tapRecognizer.cancelsTouchesInView = NO;
그래서 탭 인식기가 모든 탭을 잡는 유일한 사람이 되는 것을 방지합니다.
업데이트 - Michael이 이 속성을 설명하는 문서에 대한 링크를 언급했습니다. 취소터치 인 뷰
Kevin Ballard의 답변에 대한 후속 조치로, 저는 이와 같은 문제를 겪었고 결국 이 코드를 사용하게 되었습니다.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isKindOfClass:[UIButton class]]){
return NO;
}
return YES;
}
동일한 효과를 제공하지만 모든 뷰 깊이의 UIButton에서 작동합니다(내 UIButton은 여러 뷰 깊이였고 UIGesture Recognizer의 대리자는 이에 대한 참조가 없었습니다).
iOS 6.0 이상에서는 기본 제어 동작이 제스처 인식기 동작의 중복을 방지합니다.예를 들어, 단추의 기본 작업은 한 번 탭입니다.단추의 상위 보기에 연결된 단일 탭 제스처 인식기가 있고 사용자가 단추를 누르면 단추의 동작 방법이 제스처 인식기 대신 터치 이벤트를 수신합니다.이는 다음을 포함하는 컨트롤의 기본 동작과 겹치는 제스처 인식에만 적용됩니다.
이 답변들은 불완전했습니다.저는 이 부울 연산을 사용하는 방법에 대해 여러 개의 게시물을 읽어야 했습니다.
*.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 ...");
}
여기서 다른 방법을 찾았습니다.그것은 각 버튼 안에 있든 없든 터치를 감지합니다.
- (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]);
}
스위프트 5
탭 제스처가 있는 수퍼 뷰의 버튼
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
if let _ = touch.view as? UIButton { return false }
return true
}
저의 경우 hitTest를 구현하는 것이 저에게 효과가 있었습니다.버튼이 있는 컬렉션 뷰가 있습니다.
이 메서드는 다음을 호출하여 보기 계층을 통과합니다.point(inside:with:)
터치 이벤트를 수신할 서브뷰를 결정하는 각 서브뷰의 방법.한다면point(inside:with:)
하는 가장 뷰의 가 유사하게 합니다. true를 반환합니다.
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
guard isUserInteractionEnabled else { return nil }
guard !isHidden else { return nil }
guard alpha >= 0.01 else { return nil }
guard self.point(inside: point, with: event) else { return nil }
for eachImageCell in collectionView.visibleCells {
for eachImageButton in eachImageCell.subviews {
if let crossButton = eachImageButton as? UIButton {
if crossButton.point(inside: convert(point, to: crossButton), with: event) {
return crossButton
}
}
}
}
return super.hitTest(point, with: event)
}
여기 제게 효과가 있었던 릴리 발라드의 스위프트 버전의 답변이 있습니다.
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
if (scrollView.superview != nil) {
if ((touch.view?.isDescendantOfView(scrollView)) != nil) { return false }
}
return true
}
다음 부울을 설정하여 UITapGesture Recognizer가 다른 이벤트(예: 버튼 탭)를 취소하지 않도록 할 수 있습니다.
[tapRecognizer setCancelsTouchesInView:NO];
시나리오가 다음과 같은 경우:
보기가 단순하고 UI 버튼이 몇 개 있습니다.해당 뷰에 하위 뷰로 추가된 UITextField 컨트롤.이제 컨트롤(추가한 하위 보기)을 제외한 보기의 다른 위치를 누르면 키보드가 해제됩니다.
솔루션은 다음과 같습니다.
다음 메서드를 XYZViewController.m(사용자의 보기가 있는)에 추가합니다.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
cdasher의 대답을 최적화하는 것은, 당신은 이해합니다.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch
{
return ![touch.view isKindOfClass:[UIControl class]];
}
언급URL : https://stackoverflow.com/questions/3344341/uibutton-inside-a-view-that-has-a-uitapgesturerecognizer
'programing' 카테고리의 다른 글
null 값에 대한 zure 테이블 저장소 쿼리 (0) | 2023.05.18 |
---|---|
Python 프로젝트에서 상대 경로를 사용하여 파일 읽기 (0) | 2023.05.18 |
키 값 데이터 저장소에 디렉터리 계층 저장 (0) | 2023.05.18 |
3차 연산자 VB vs C#: 왜 아무것도 0으로 해결하지 않습니까? (0) | 2023.05.18 |
Pymongo 결과에서 _id 요소 제거 (0) | 2023.05.18 |