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;
您在YLSRegisterStepOneView
的initWithFrame:
方法中添加按钮,不是吗?
所以这里的[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 偶尔会在响应者链中丢失?的主要内容,如果未能解决你的问题,请参考以下文章
如何让 UITableView 标题视图出现在响应者链中的表格单元格之前?
UIControl 如何将所有触摸事件传递给响应者链中的下一个对象?