【问题标题】:subviews are not receiving touches子视图没有收到触摸
【发布时间】:2011-05-03 17:15:40
【问题描述】:

我有添加 2 个子视图的主视图控制器。

- (void)viewDidLoad
{
    [self init];
    [super viewDidLoad];

    //To shrink the view to fit below the status bar.
    self.wantsFullScreenLayout = YES;

    //We start off by displaying the background Images.
    [self displayMenuSceneBackground];

    //Then we show the Menus.
    [self displayMenuSceneMenu];


}

这里我们将子视图添加到主视图控制器。两个子视图都是使用界面构建器构建的视图控制器。

-(void) displayMenuSceneBackground{
    //Display the MenuSceneBackground View Controller
    MenuSceneBackground *screen = [[MenuSceneBackground alloc] init];

    [self.view addSubview:screen.view];
    [screen release];
}

-(void) displayMenuSceneMenu{
    //Display the MenuSceneMenu View Controller
    MenuSceneMenu *screen = [[MenuSceneMenu alloc] init];

    [self.view addSubview:screen.view];
    [screen release];
}

两个子视图都正确显示,即使是 MenuSceneBackground 视图控制器中的一些动画也可以正常工作,但是这些子视图都没有接收到触摸事件。

它们都实现了 touchesBegan,但只有主视图控制器接收它们。

我尝试将主视图控制器 userInteraction 设置为 NO,并且没有实现 touchesBegan 方法,但这只会使触摸被忽略。

两个子视图都显示在整个屏幕尺寸上。

我确实读过类似的问题,但回答没有帮助。

我在子视图中有这个

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];

    NSLog(@"testing MenuSceneMenu");
    [self clicked_testing_alert];    //This is a UIAlertView for debugging
    return;
}

提前感谢您的帮助。

【问题讨论】:

  • 是否为两个子视图启用了用户交互?
  • 是的,他们都有用户交互到 YES。
  • 在您的 touchesBegan 方法中,您是做什么的?您是否在它们的开头放置了一个简单的 NSLog 来验证它们是否被调用?
  • 我已经编辑了我的问题以在子视图中显示 touchesBegan 方法。

标签: objective-c ios touches


【解决方案1】:

请注意,UIViewController 与 UIView 不同,因此不会接收 touchesBegan 事件。 (您在视图控制器中添加了 touchesBegan,而不是在视图中...)。

解决方案:感谢 Simon Goldeen,我发现在一个演示项目中,touchesBegan 被调用了。但是,在我的生产项目中,它没有。事情是这样的:(正如 Apple 建议的那样)你和我正在使用 - (void)release; 来减少内存使用量。 这会导致不调用 touchesBegan。西蒙不使用release,所以在他的情况下,他们确实会被调用。

【讨论】:

  • UIViewController 是 UIResponder 的子类,如果其视图没有响应该方法,则会接收 -touchesBegan: 方法调用。
  • 它没有。这是有道理的,因为你不能触摸视图控制器,你触摸视图控制器拥有(控制)的视图......
  • 我了解您的回复。我现在要去对代码做一些更改。感谢你们俩的快速回复。 brb
  • 我刚刚编写了一个快速测试应用程序来验证 UIViewController 确实收到了-touchesBegan: 方法调用。
  • 没办法 :|... #正在自己编写一个测试应用程序... 编辑:对不起,确实如此(这没有意义,因为文档的某些部分甚至说它不起作用)...
【解决方案2】:

我很确定问题出在你打电话给[super touchesBegan:touches withEvent:event];

来自该方法的 UIResponder 文档:

这个方法的默认实现什么都不做。然而,UIResponder 的直接 UIKit 子类,尤其是 UIView,会将消息向上转发到响应者链。

因此,UIViewController 的默认行为是将触摸传递到响应者链。由于这不是您想要做的事情(至少不是立即),您应该从代码中删除该行,或者在您确定不需要或不想响应当前视图中的触摸后将其包含在内.

【讨论】:

  • 删除该行不起作用,我实际上有没有该行的原始方法,但添加它希望它会有所帮助
  • 删除该行会适得其反。由于超级检查应该调用哪些子视图,一些子视图现在将不再被调用。您还应该注意,iOS 是从根到细节工作的,这意味着它将从您的 UIWindow 开始,并最终在包含特定触摸位置的最深嵌套 UIView 中结束。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多