ViewController 偶尔会在响应者链中丢失?

Posted

技术标签:

【中文标题】ViewController 偶尔会在响应者链中丢失?【英文标题】:ViewController occasionally miss in responder chain? 【发布时间】:2014-01-03 02:18:20 【问题描述】:

我今天遇到了一件很奇怪的事情:我的自定义 ViewController 偶尔会在响应者链中丢失

首先我有一个自定义 UIView,它的子视图是 UIButton,然后我像往常一样设置目标操作:

[closeButton addTarget:self.controller action:@selector(closeButtonPressed) forControlEvents:UIControlEventTouchUpInside];

当然,我在自定义 UIViewController 中实现了 closeButtonPressed 方法

在大多数情况下,它运行良好。但是偶尔我的ViewController会错过tap事件,最后我发现,tap事件传给了AppDelegate,调用了AppDelegate中的closeButtonPressed方法!

我花了一整天的时间解决这个问题,但仍然不知道为什么。你能给我一个线索吗?多谢。以下是代码,希望对您有所帮助:

初始化并呈现我的 ViewController 和 View 的代码:

YLSRegisterStepOneViewController *step1Controller = [[YLSRegisterStepOneViewController alloc] initWithNibName:nil bundle:nil];
step1Controller.view = [[YLSRegisterStepOneView alloc] initWithFrame:CGRectMake(0, 0, 540, 720) OperType:operType];
step1Controller.modalPresentationStyle = UIModalPresentationFormSheet;
step1Controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;   
[self presentViewController:step1Controller animated:YES completion:nil];

UIView的代码:

UIButton *closeButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
closeButton.frame = CGRectMake(10, 10, 50, 50);
[closeButton setTitle:NSLocalizedString(@"button_close", @"") forState:UIControlStateNormal];
[closeButton addTarget:self.controller action:@selector(closeButtonPressed) forControlEvents:UIControlEventTouchUpInside];

[self addSubview:closeButton];

UIViewController的代码:

-(void) closeButtonPressed

    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];// to dismiss self

附加:除了 UIButton,还有一个 UITextField。当这个问题发生时,如果我点击 UITextField,然后点击 UIButton,UIViewController 工作正常

【问题讨论】:

您是否在YLSRegisterStepOneView 中设置了属性controller 在第一个版本中,我没有设置,但是由于响应链,代码可以工作......然后我发现这个问题,并尝试设置控制器属性,但问题仍然存在。最让我困惑的是:它不是每次都发生,而是偶然,偶尔发生 你能告诉我你是如何设置属性的吗? 对不起,我不知道如何在评论中粘贴代码,所以我将它们粘贴在第二个答案中,请看那里 您可以在此处编辑您的问题... 【参考方案1】:

您像这样设置YLSRegisterStepOneView 的控制器属性:

YLSRegisterStepOneViewController *step1Controller = [[YLSRegisterStepOneViewController alloc] initWithNibName:nil bundle:nil];
YLSRegisterStepOneView *step1View = [[YLSRegisterStepOneView alloc] initWithFrame:CGRectMake(0, 0, 540, 720) OperType:operType];
step1Controller.view = step1View;
step1View.controller = step1Controller;

您在YLSRegisterStepOneViewinitWithFrame: 方法中添加按钮,不是吗?

所以这里的[closeButton addTarget:self.controller action:@selector(closeButtonPressed) forControlEvents:UIControlEventTouchUpInside]; self.controller 仍然为零。

step1View.controller = step1Controller;[closeButton addTarget:self.controller action:@selector(closeButtonPressed) forControlEvents:UIControlEventTouchUpInside]; 之后调用

更新: 您说响应者链让您感到困惑,我认为问题在于您分配视图控制器的视图属性,例如 step1Controller.view = step1View;,这是不推荐的。如果您想将自定义视图用作 viewcontroller 的视图,请执行以下操作:

覆盖视图控制器中的loadView 方法。 您可以覆盖此方法以手动创建视图。如果您选择这样做,请将视图层次结构的根视图分配给视图属性。您创建的视图应该是唯一的实例,并且不应与任何其他视图控制器对象共享。此方法的自定义实现不应调用 super。

- (void)loadView

    YLSRegisterStepOneView *step1View = [[YLSRegisterStepOneView alloc] initWithFrame:CGRectMake(0, 0, 540, 720) OperType:operType];
    self.view = step1View ;

【讨论】:

哦,是的!我多么愚蠢。我觉得有道理,我会试试你说的。但是我仍然很困惑为什么偶尔会发生这种情况,我认为即使目标为零,响应者链机制也应该做点什么......但至少,也许你指出了解决这个问题的方法 是的,现在我在初始化 UIView 时设置了控制器属性,它工作正常。谢谢你,朋友。但是响应者链仍然让我感到困惑,我会跟随它【参考方案2】:

我看不到您在哪里设置您在此处传递的自定义视图的控制器属性:

[closeButton addTarget:*self.controller* action:@selector(closeButtonPressed) forControlEvents:UIControlEventTouchUpInside];

我认为,如果您在视图中创建/设置控制器属性,它将解决问题(除非您已经这样做但代码不在这里)。

【讨论】:

您好,谢谢您的回复。实际上我已经尝试过你说的,但它不起作用。事实上,当我设置控制器属性时,ViewController 仍然偶尔会错过该事件。让我感到困惑的是:这种情况偶尔会发生,不是每次都发生

以上是关于ViewController 偶尔会在响应者链中丢失?的主要内容,如果未能解决你的问题,请参考以下文章

如何在响应者链中保持隐藏视图?

iphone响应程序链中操作方法所需的可见性是啥?

如何让 UITableView 标题视图出现在响应者链中的表格单元格之前?

UIControl 如何将所有触摸事件传递给响应者链中的下一个对象?

1% 的时间没有处理 UIButton 事件:我应该在我的响应链中责备谁?

为啥偶尔会在 ListView 中加载错误的图像?