0

我一直在寻找解决方案,但没有幸运找到一个。如果以前有人问过,也许有人可以指出来,或者帮助我一个想法。

我有UIViewController该主机拖曳自定义视图。第一个自定义视图是全屏。第二个自定义视图,实际上是一个菜单,从屏幕底部滑入视图,类似于带有自定义动画的工具栏,然后它应该滑出。

当前配置:菜单在延迟后滑入视图(视图出现后),并且 NSTimer 开始计数。它会在视图中停留几秒钟,直到 NSTimer 触发另一个方法,并且该方法将菜单收回。

一切正常。

我想要什么:如果用户开始与菜单、切换开关、滑块等进行交互,我希望菜单留在视图中,延迟 NSTimer 的触发,直到用户完成交互。然后收回菜单。

为此,我在将菜单滑入视图的方法中使用了 NSTimer,以触发在 X 毫秒后收回菜单的其他方法。

在收回菜单的方法中,我使计时器无效。

我覆盖了该tocuhesBegan方法,以查看交互区域是否在菜单的边界内,如果是,则将 NSTimer 重置为另一个 X 毫秒。

问题:如果用户触摸菜单的背景,那很好,但是如果用户与菜单内的开关、按钮和幻灯片进行交互,menu.view则不会注册触摸,这是有道理的,因为它们是最前线并耗尽了触摸事件,因此触摸事件不会向下传递。但另一方面,这是我的问题!

我不能touchesBegan覆盖menu.view. 我还能如何注册 menu.view 区域中发生的那些触摸?

我试图locationInView:nil在窗口内进行触摸,但这也没有记录与按钮和滑块等的交互。

谢谢。

4

1 回答 1

1

捕获视图层次结构中出现的所有触摸事件的一种解决方案是提供自定义 UIWindow 实现并覆盖该sendEvent方法。所有事件都由第一个接收,UIApplication然后分派到,然后再分派UIWindowUIView包含触摸点的位置。通过在 UIWindow 级别捕获事件,您可以确保可以拦截每个事件,而无需覆盖每个控件。

创建一个自定义 UIWindow 类并sendEvent像这样实现:

- (void)sendEvent:(UIEvent *)event 
{
    // Notify app to reset menu timer
    // ...

    [super sendEvent:event];
}

要使用您的自定义 UIWindow 而不是原版的,取决于您的 UI 是如何实现的。如果您使用的是 Storyboard,那么您需要window在您的应用程序委托上实现一个 getter 方法,如下所示:

- (UIWindow*)window
{
    if (!_window) {
        _window = [[CustomWindow alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
    }

    return _window;
}

application:didFinishLaunchingWithOptions:否则,在应用程序委托的方法中创建自定义 UIWindow 的实例,而不是标准的实例。

您有多种接收触摸事件通知的选项。您可以使用 NSNotificationCenter 发送和订阅自定义通知,或者您可以在自定义 UIWindow 上实现委托属性并将 UIViewController 设置为接收触摸事件通知的委托。

于 2012-01-31T18:29:37.377 回答