Iphone 手势识别器和按钮动作
我的视图层次结构如下所示:Iphone 手势识别器和按钮动作,iphone,uibutton,conflict,uigesturerecognizer,ibaction,Iphone,Uibutton,Conflict,Uigesturerecognizer,Ibaction,我的视图层次结构如下所示: 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 Rec
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手势识别器捕获/覆盖按钮的触动内部事件
我怎样才能让它工作?我认为响应者链层次结构将确保按钮触摸事件将被优先考虑,它将被触发!我错过了什么
以下是一些相关代码:
#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
这是来自苹果的例子
- (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;
}
希望能有所帮助
编辑
正如Daniel指出的,您必须遵守UIgestureRecognitizerDelegate
,它才能工作
沙尼我也有同样的问题,然后我试着用
- (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类类型)GestureRecognitizer应该开始,它不会工作。我认为最好的解决方案是使用下面的代码片段:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
CGPoint touchLocation = [touch locationInView:self.view];
return !CGRectContainsPoint(self.menuButton.frame, touchLocation);
}
以下是Swift版本:
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
if (touch.view!.isKindOfClass(UIButton)) {
return false
}
return true
}
别忘了:
UIgestureRecognitizerDelegate
tapper.delegate=self
)这是一个Swift 3.0版本:
extension UIViewController: UIGestureRecognizerDelegate {
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
if touch.view is UIButton {
return false
}
return true
}
别忘了:
将您的tapper对象委托给self(例如:tapper.delegate=self)
啊!!!是的,我忘记了这个-手势识别器:shouldReceiveTouch:方法。谢谢你给我指明了正确的方向。虽然这解决了我的问题,但我仍然不知道为什么响应者层次结构在这种情况下不起作用。它可能应该这样做,但苹果没有处理它。UIgestureRecognitor的行为被清楚地描述为与“正常”响应程序链分离。这是Apple的一个设计决定。记住遵照UigesturrErgOngIZError协议并将uigesturreCngnisher的委托设置为该对象。为了更广泛的使用,请考虑Ramesh或FrigBoT的测试子句的一些变体。例如,在我的例子中,我以以下行结束:如果([touch.view isKindOfClass:[UIControl类]]| |[[touch.view superview]isKindOfClass:[UITableViewCell类]]){
…注意tableview单元格被“触摸”在他们的contentView中,它是一个私有类的成员,因此我们在这里检查superview的类。谢谢你的回答!在我的情况下,我遇到了相同的问题,但直到我在实际设备中进行测试后才发现它。在模拟器中运行应用程序而不使用UIGestureDelegate,如回答中所示,效果与预期一样虽然不正确。我只错过了myGestureRecognizer.delegate=self;
最简单的方法是将cancelsTouchesInView=false