iOS/ObjC:“后备”轻击手势识别器?

Posted

技术标签:

【中文标题】iOS/ObjC:“后备”轻击手势识别器?【英文标题】:iOS/ObjC: "Fallback" tap gesture recognizer? 【发布时间】:2015-06-28 13:18:46 【问题描述】:

我有一个 UIViewController 子类,它的视图通常包含一些 UIButton 和其他交互元素,这些元素可能附加一个或多个手势识别。

我想要做的是在用户点击屏幕的非交互部分时提供一些视觉反馈。换句话说:当用户在任何地方点击屏幕时,当且仅当视图中没有其他控件响应触摸事件(包括如果它是,比如说,拖动的开始),那么我想触发一个基于在水龙头的位置上。

有没有一种直接的方法来做到这一点,不需要需要我将任何额外的逻辑附加到视图中的交互式元素,或者至少允许我通过遍历自动附加这样的逻辑查看层次结构?

【问题讨论】:

【参考方案1】:

你可以覆盖容器视图的pointInside:withEvent:方法,如果点击位置下有交互元素,则返回NO,否则返回YES。返回YES 的情况将对应于点击空白位置。

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

    // Perform some checks using the CGRectContainsPoint method
    // e.g. CGRectContainsPoint(oneOftheSubviews.frame, point)   

一个不错的选择是使用hitTest:withEvent: 方法,如下例所示:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

    UIView *hitView = [super hitTest:point withEvent:event];
    if (hitView != someView) return nil;
    return hitView;

[super hitTest:point withEvent:event] 将返回被点击的视图层次结构中最深的视图。

因此您可以检查hitView 的类型,如果它对应于您的交互式子视图之一,则返回它。如果它等于self,则表示点击位置下没有子视图,在您的情况下,这意味着用户点击了空白区域。在这种情况下,您将做任何您想做的事,然后返回nil

【讨论】:

如果没有交互元素列表,我怎么能知道那里是否有交互元素? (详细说明:很多交互元素都包含在第三方控件中,所以我并不总是知道它们是什么) 请看我更新的答案。在所有情况下,您都需要能够确定您获得的子视图是否是您想要的交互式视图之一。没有一种自动的方式来做你需要的事情。但是您不需要向子视图添加任何自定义逻辑。 不是我所希望的,但正如你所说,我认为我所希望的可能实际上是不可能的。最终创建了一个 UIView 子类,其中包含一个 NSArray 属性,其中包含它应该放弃触摸的所有 UIView,并使用 pointInside 方法。 我认为您可以使用hitTest 方法来确定用户是否点击了UIControl 子类。它们是标准控件还是第 3 方控件并不重要。

以上是关于iOS/ObjC:“后备”轻击手势识别器?的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发之手势识别

iOS开发之手势识别汇总

iOS开发中六种手势识别

iOS开发UI高级手势识别器

iOS - 多次点击手势识别器

iOS 手势