[英]Gesture recognizer and button actions
我有一个看起来像这样的视图层次结构:
UIView (A)
UIView > UIImageView
UIView > UIView (B)
UIView > UIView (B) > Rounded Rect Button
UIView > UIView (B) > UIImageView
UIView > UIView (B) > UILabel
我已将手势识别器附加到我的 UIView (B) 上。 我面临的问题是,我没有对 UIView (B) 内的圆角矩形按钮执行任何操作。 singleTap 手势识别器捕获/覆盖按钮的 Touch Up Inside 事件。
我怎样才能让它工作? 我认为响应者链层次结构将确保优先考虑按钮触摸事件,并且它会被触发! 我错过了什么?
这是一些相关的代码:
#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;
}
}
在“shouldReceiveTouch”方法中,您应该添加一个条件,如果触摸位于按钮中,则该条件将返回 NO。
这是来自苹果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;
}
希望它会有所帮助
编辑
正如丹尼尔指出的那样,您必须符合UIGestureRecognizerDelegate
才能使其工作。
沙尼
我也有同样的问题,然后我尝试
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
if ([touch.view isKindOfClass:[UIButton class]]) { //change it to your condition
return NO;
}
return YES;
}
它现在完美地工作.......
一般来说,我们使用下面的委托方法来避免各种 UIControl 中的触摸:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if (([touch.view isKindOfClass:[UIControl class]])) {
return NO;
}
return YES;
}
注意:不要做这个检查(检查recognizer.view 类类型)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 (eg: tapper.delegate = self)
这是一个 Swift 版本:
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
if (touch.view!.isKindOfClass(UIButton)) {
return false
}
return true
}
不要忘记:
UIGestureRecognizerDelegate
tapper.delegate = self
)我认为最好的解决方案是使用下面的代码片段:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
CGPoint touchLocation = [touch locationInView:self.view];
return !CGRectContainsPoint(self.menuButton.frame, touchLocation);
}
Vivienne 的 Swift 版本回答:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
let location = touch.location(in: view)
return !someView.frame.contains(location)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.