手势识别和按钮动作
我有一个看起来是这样的视图层次:手势识别和按钮动作
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)内的Rounded Rect按钮的任何操作。 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”的方法。
这是来自苹果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
为它工作。
SHANI
啊!是的,我忘了这个-gestureRecognizer:shouldReceiveTouch:方法。感谢您指点我正确的方向。虽然这解决了我的问题,但我仍然不知道为什么响应者层次结构在这种情况下不起作用。它可能应该,但它不是由苹果公司处理。 – Mustafa 2011-01-28 07:29:25
UIGestureRecognizer行为被清楚地描述为与“普通”响应者链分开。 这是由Apple设计决定的。 – 2011-02-17 12:48:15
我也有同样的问题,那我就用
- (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;
}
注意:不要做这种检查(C heck the recognitionizer.view类类型)gestureRecognizerShouldBegin,它不会工作。
最好的解决办法是在我的脑海使用下面的代码片段:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
CGPoint touchLocation = [touch locationInView:self.view];
return !CGRectContainsPoint(self.menuButton.frame, touchLocation);
}
这里是一个斯威夫特版本:
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
if (touch.view!.isKindOfClass(UIButton)) {
return false
}
return true
}
不要忘记:
- 让你类符合
UIGestureRecognizerDelegate
- 使您的tapper对象de legate to self(例如:
tapper.delegate = self
)
这是斯威夫特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)
最简单的方法是设置cancelsTouchesInView =假 – 2017-06-02 10:10:12