需要在 iOS 的覆盖视图中阻止除特定触摸之外的所有触摸

Posted

技术标签:

【中文标题】需要在 iOS 的覆盖视图中阻止除特定触摸之外的所有触摸【英文标题】:Need to block all touches except for specific one in an overlay view for iOS 【发布时间】:2014-02-16 06:46:09 【问题描述】:

我正在尝试设置一个教程类型类,该类呈现一个覆盖视图并需要用户在继续之前执行操作。我目前的层次结构设置如下。

UIWindow 
|---- UIViewController 
|     |---- UIViewA (View performing tutorial action on)
|     |---- UIViewB
|
|---- UIViewT (tutorial overlay)
      |---- CGRect (defined by UIViewA)

在教程过程中,视图会被拖拽,新视图会被创建等等,这就是为什么我将教程覆盖视图添加到 UIWindow。这样,我就不必像 SO 上的许多地方所建议的那样弄乱视图控制器中的视图层次结构。覆盖窗口的目的是阻止所有操作,教程预期的必需操作除外。

目前教程覆盖视图实现如下

@interface ZSOverlayView : UIView <UIGestureRecognizerDelegate>

@property (nonatomic, assign) CGRect activeRegion;

@end

@implementation ZSOverlayView

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
    return !CGRectContainsPoint(_activeRegion, point);


@end

其中 activeRegion 是 UIViewA 定义的 CGRect。这成功地阻止了所有不需要的事件和手势,使其无法通过 activeRegion 之外的覆盖。在这种特定情况下,UIViewB 不会获取事件或手势。

问题在于,对于 UIViewA,我只想要一个手势,而不是所有手势。例如,如果 UIViewA 具有双击、平移和自定义手势,我可能只希望双击激活一次,或者自定义手势一次激活,或者两者兼而有之。本教程不知道视图有哪些手势,因此它需要一种通用的方式来传递所需的手势,并阻止那些没有的手势。目前没有任何手势被阻止。即使我已经设置了标志,我目前正在这样做,以确定哪些手势应该能够通过,但我仍然遇到了如何阻止特定手势并让其他手势通过的问题。

我不确定如何继续,因为教程覆盖不是任何手势识别器的委托,我也不希望它是,因为通过接管作为委托,教程可能会删除现有委托指定的特殊条件.

任何想法如何继续获得我正在寻找的功能?

【问题讨论】:

您能否澄清一下这种说法:“我也不希望它出现在由适当代表处理的特殊情况下”? 我更新了问题的结尾,希望现在更清楚了。 如果我理解正确,您可以设置 UIGestureRecognizerDelegates 然后在委托方法中使用条件来指定当手势视图是教程窗口与手势视图是主窗口时要做什么. 我花了很多时间研究不同的解决方案,但我从来没有想过那个。我很确定它会起作用,但我试图使本教程通用,而不是将它过多地集成到现有代码中。为了清楚起见,您是说在教程视图是手势视图时修改已经存在的代表以采取不同的行动?这是有效地做到这一点的唯一方法吗? 是的,这就是我要说的。除了修改现有的委托方法并添加这些条件之外,我不知道有任何其他方法。 【参考方案1】:

我不太喜欢这个解决方案,但最好的答案是 Lyndsey Scott 在 cmets 中给出的。

如果我的理解正确,您可以设置 UIGestureRecognizerDelegates 然后在委托方法中使用条件来指定当手势视图是教程窗口与手势视图是主窗口时要做什么。

我宁愿不依赖这种方法,因为我试图让我的教程库完成所有工作,但由于有一段时间没有答案,我只是想把它扔在那里工作。

【讨论】:

【参考方案2】:

您是否尝试过仅使用 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event ?

如果你想阻止触摸事件,你可以在这里这样做:

防止视图的触摸事件 调用辅助方法以确定可以触摸哪些视图 等

编辑:迟到总比永不好。我实际上遇到了需要这样做(再次......)并且(再次)在下面的 cmets 中找到了我所指的答案 =]

无论如何,使用 touchesBegan,您可以这样做(以获取所有正在接收您正在寻找的触摸(或触摸)类型的手势识别器:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 

    // In this example, I'm only actually looking for (and caring) about a single touch.
   if( [touches count] == 1 ) 
       UITouch *touch = (UITouch *)[touches anyObject];
       // So here they are now
       NSArray *gestureRecognizersForTouch = [touch.gestureRecognizers copy];
      // ... whatever else.
   

此时,您可以删除识别器,将值设置为他们都可以在您的对象中访问的属性,提交通知等等等等。

【讨论】:

我看过它,但我认为它没有帮助,因为我需要让手势通过或阻止它们,我找不到从 UIEvent 和一个创建 UIGestureRecognizer 的方法点集。例如,我无法知道 UIEvent 是双击还是滑动,是吗? 这是一种(过于复杂)的方法:***.com/questions/14726087/… 另一种方法是创建一个通用的手势识别器并听取所有的手势(这是一种普遍使用的模式网络)。我有一个很好的链接,让我很快找到它。但是,是的,你应该能够做你正在寻找 Bleh 的事情,这是我正在谈论的代码:(void)handleTapGesture:(UITapGestureRecognizer *)sender // sender.state == UIGestureRecognizerStateRecognized 例如 meh,n/m 抱歉,我现在找不到链接。我明天再回来看看,如果没有人回答,我会找到并发布它。 (仅供参考,该代码显然只列出了基于点击的手势......但它是一个开始 =P)

以上是关于需要在 iOS 的覆盖视图中阻止除特定触摸之外的所有触摸的主要内容,如果未能解决你的问题,请参考以下文章

UIView clipToBounds 没有停止子视图接收父视图之外的触摸

SWIFT:检测当前视图之外的触摸

从 UITableViewCell 中删除除 imageView 之外的所有子视图

iOS - 背景视图正在消耗触摸事件

UITapGestureRecognizer 在子视图中阻止 UIButton 的触摸事件

UIControl 轨道触及其视图之外