UIButton在具有UITapGestureRecognizer的视图中

时间:2010-07-27 13:54:32

标签: ios objective-c iphone cocoa-touch uitapgesturerecognizer

我有一个UITapGestureRecognizer的视图。因此,当我点击视图时,此视图上方会出现另一个视图。这个新视图有三个按钮。当我现在按下其中一个按钮时,我没有按下按钮动作,我只进行了轻击手势动作。所以我不能再使用这些按钮了。我该怎么做才能将事件传递给这些按钮?奇怪的是按钮仍然突出显示。

我收到它后,我不能删除UITapGestureRecognizer。因为有了它,也可以删除新视图。意味着我想要一个行为,如全屏视频控件

12 个答案:

答案 0 :(得分:244)

您可以将控制器或视图(以创建手势识别器为准)设置为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
}

答案 1 :(得分:155)

作为凯西跟随凯文巴拉德回答的后续行动:

- (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
}

这基本上使所有用户输入类型的控件如按钮,滑块等工作

答案 2 :(得分:99)

在此处找到此答案:link

您也可以使用

tapRecognizer.cancelsTouchesInView = NO;

这会阻止点击识别器成为唯一能够捕获所有点击的人

更新 - Michael提到了描述此属性的文档的链接:cancelsTouchesInView

答案 3 :(得分:71)

作为Kevin Ballard的回答,我遇到了同样的问题并最终使用了这段代码:

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

它具有相同的效果,但这适用于任何视图深度的任何UIButton(我的UIButton有几个视图深,而UIGestureRecognizer的委托没有对它的引用。)

答案 4 :(得分:10)

在iOS 6.0及更高版本中,默认控件操作可防止重叠手势识别器行为。例如,按钮的默认操作是单击。如果您将单击手势识别器附加到按钮的父视图,并且用户点击该按钮,则该按钮的操作方法将接收触摸事件而不是手势识别器。这仅适用于与控件的默认操作重叠的手势识别,其中包括:.....

From Apple's API doc

答案 5 :(得分:8)

这些答案不完整。我必须阅读有关如何使用此布尔操作的多篇帖子。

在* .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 ...");

}

答案 6 :(得分:7)

here找到另一种方法。它会检测每个按钮内部是否有触摸。

(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]);
}

答案 7 :(得分:3)

以下是适用于我的Lily Ballard's answer的Swift版本:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    if (scrollView.superview != nil) {
        if ((touch.view?.isDescendantOfView(scrollView)) != nil) { return false }
    }
    return true
}

答案 8 :(得分:1)

您可以通过设置以下布尔值来停止UITapGestureRecognizer取消其他事件(例如点击按钮):

    [tapRecognizer setCancelsTouchesInView:NO];

答案 9 :(得分:1)

如果您的方案是这样的:

您有一个简单的视图和一些UIButtons,UITextField控件作为子视图添加到该视图。现在,除了控件(您添加的子视图)之外,当您触摸视图上的任何其他位置时,您想要关闭键盘

然后解决方案是:

将以下方法添加到XYZViewController.m(具有您的视图)

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.view endEditing:YES];
}

答案 10 :(得分:1)

优化cdasher的答案,你得到

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
       shouldReceiveTouch:(UITouch *)touch 
{
    return ![touch.view isKindOfClass:[UIControl class]];
}

答案 11 :(得分:0)

快速5

带有手势的超级视图上的按钮

var profileButton: some View {
    Button(action: { class.showingProfile.toggle() }) {
        Image(systemName: "person.crop.circle")
            .imageScale(.large)
            .accessibility(label: Text("User Profile"))
            .padding()
}}