在 UINavigationController 中未检测到 touchesBegan 和其他触摸事件
Posted
技术标签:
【中文标题】在 UINavigationController 中未检测到 touchesBegan 和其他触摸事件【英文标题】:touchesBegan and other touch events not getting detected in UINavigationController 【发布时间】:2010-06-14 16:36:43 【问题描述】:简而言之,我想检测导航控制器标题栏上的触摸,但实际上根本无法捕捉到任何触摸!
一切都在没有 IB 的情况下完成,如果这有影响的话。
我的应用代理的 .m 文件包含:
MyViewController *viewController = [[MyViewController alloc] init];
navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
[window addSubview:navigationController.view];
在此窗口中添加了一些其他子视图,这些子视图覆盖了 navigationController,只留下了导航栏可见。
MyViewController 是 UIViewController 的子类,其 .m 文件包含:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
for (UITouch *touch in touches)
NSLog(@"ended\n");
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
for (UITouch *touch in touches)
NSLog(@"began\n");
我也尝试将这些函数直接放入应用代理的 .m 文件中,但控制台仍为空白。
我做错了什么?
【问题讨论】:
我的应用程序的整体设置是使用应用程序委托中的 [window addSubview:...] 按顺序添加到窗口的 UINavigationController、UIScrollView 和 UIPageControl。然后 ScrollView 包含更多具有应用程序实际内容的视图。 UINavigationController 的按钮工作正常,但没有检测到对标题的触摸。 touchesEnded 和 begin 是 UIView 方法而不是 UIViewController Daniel 是对的……这些永远不会在 UIViewController 中被调用。您需要使用这些方法创建一个 UIView 子类,然后将其分配给 viewController.view 或将其作为子视图添加到 viewController 的视图中(您可能会在 viewController 的 loadView 方法中执行这些操作。 我尝试分配一个自定义 viewController.view 但这似乎并没有在导航栏上进行触摸。如果我摆脱所有其他视图,只留下 navigationController 和其中的视图,它只会拾取视图内部的触摸,而不是栏。 @Daniel: touchesBegan/Ended 不是 UIView 方法,它们是 UIResponder 方法,而 UIViewController 是 UIResponder。 【参考方案1】:好吧,由于没有更好的主意,我在我的应用程序中添加了另一个子视图,颜色清晰,以编程方式放置在导航栏标题上,并为该视图使用了一个自定义类,并覆盖了相关的触摸方法。工作正常,但我仍然希望有一个更优雅的解决方案。
【讨论】:
@Daniel 不,这样就完美了。如果我们遇到同样的问题,通过编辑将答案嵌入到问题中会使我们更难找到解决方案。【参考方案2】:视图控制器被插入到其托管视图和父视图之间的响应者链中:
因为视图控制器与它们管理的视图紧密绑定,它们也是用于处理事件的响应者链的一部分。视图控制器本身是 UIResponder 类的后代,并被插入到托管视图与其父视图之间的响应者链中。因此,如果视图控制器管理的视图不处理事件,它会将事件传递给其视图控制器,然后视图控制器可以选择处理事件或将其转发给视图的父视图。
(UIViewController documentation)
是否有可能,您的控制器的托管视图正在吞噬所有事件?是什么样的景色?
【讨论】:
我对此相当陌生,对整个视图/控制器关系并不熟悉,但就我而言,MyViewController 中的视图实际上是空白的。我只是尝试制作一个自定义 UIView 子类并从那里覆盖 touches 方法,然后将该子类用于该控制器的视图,但这也不起作用。这个 MyViewController 的唯一目的是提供一个带有按钮和标题的导航栏。【参考方案3】:遇到了麻烦,因为我的自定义视图在视图层次结构中更深。相反,我爬上了响应者链,直到找到UIViewController
;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
// Pass to top of chain
UIResponder *responder = self;
while (responder.nextResponder != nil)
responder = responder.nextResponder;
if ([responder isKindOfClass:[UIViewController class]])
// Got ViewController
break;
[responder touchesBegan:touches withEvent:event];
【讨论】:
【参考方案4】:尝试将方法 userInteractionEnabled = YES 添加到您的 UIImageView
【讨论】:
感谢您禁用触摸的逻辑。【参考方案5】:这些方法应该放在 UIView 子类而不是 UIViewControllers...UIView 将接收触摸回调,然后你可以在 UIView 上制定一个协议并在 UIViewController 上实现它,这样 UIViewController 就会收到一些回调当触摸事件发生时......这是一个讨论协议以及如何定义和实现它们的链接Protocols Ref
【讨论】:
以上是关于在 UINavigationController 中未检测到 touchesBegan 和其他触摸事件的主要内容,如果未能解决你的问题,请参考以下文章
在 UINavigationController 内的 UITabBarcontroller 中添加 UINavigationController?
从嵌入在 UINavigationController 中的一个视图控制器到另一个 UINavigationController
(Swift) 在嵌套在 Main UINavigationController 中的 UINavigationController 和 UITabController 之间切换
关闭 UINavigationController 并呈现另一个 UINavigationController
带有主 UINavigationController 和详细 UINavigationController 的 UISplitViewcontroller