2012-03-06 60 views
1

这是一个让我有点bat and的东西,而且我的眼睛正在黯然失色。在iOS中加载视图时发生的事件顺序

我有一个导航控制器的应用程序。

查看A具有一些输入字段和“继续”按钮,它加载视图B

当我轻触导航控制器其导致事件的左上角的“返回”按钮的顺序被解雇我“M没有料到/理解

我的跟踪显示...

View B: viewWillDisappear 
View A: viewWillAppear 
View B: textFieldShouldEndEditing 

编辑 - 更详细/代码解释我以前模糊的问题

从概念上讲,以下方法一直运行良好,并通过了多轮QA测试。

总之,我正在使用textFieldShouldEndEditing来验证文本字段。如果他们无效,我会保持对该领域的关注,并向他们展示什么是错误的信息。一切都很好,验证工作可以在用户尝试从一个领域到另一个领域之间进行。

下面的代码有问题的情况是,如果有人输入部分值,然后单击BACK。整个应用程序中的所有UITextFields冻结(不允许输入),并且在某些情况下应用程序崩溃。

我试图让我发布初始问题的方法是创建一个private:BOOL isDisappearing;

,我可以在viewWillDisappear检查(在大多数情况下火灾之前textFieldShouldEndEditing),如果它是的,我会短路被烧成和冻结UITextFields /应用程序有问题的代码。

这是工作在几个视图罚款,但在'视图A:viewWillAppear'事件之前触发textFieldShouldEndEditing下面(视图B) - isDisappearing设置为'NO'以某种方式和有问题的代码是在射击textFieldShouldEndEditing

我希望这可以帮助,你可以按照。我发现很难解释没有代码 - 但我试图把它缩小到恰恰相关。我希望这里适合 - 我对社区很新。

代码VIEW B:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)rangereplacementString:(NSString *)string 
{ 
    // Enforce max lengths 
    // The return key from the keyboard counts as a character, so we have to exempt it 
if (textField.tag == ROUTING_NUMBER_TAG) 
{ 
    NSUInteger newLength = [textField.text length] + [string length] - range.length; 
    return (newLength > 9 && ![string isEqualToString:@"\n"]) ? NO : YES;   
} 
else if (textField.tag == ACCOUNT_NUMBER_TAG) 
{ 
    NSUInteger newLength = [textField.text length] + [string length] - range.length; 
    return (newLength > 17 && ![string isEqualToString:@"\n"]) ? NO : YES;   
} 
return YES; 
} 

// textField validation 
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField 
{ 
if (isDisappearing) 

    return YES; 

//run fields through validators and display validation messages. 
//IF THEY DON’T PASS VALIDATION IM "HOLDING THEM HOSTAGE" BY KEEPING THE FOCUS ON THE UITEXTFIELD (returning NO) 

if (textField.tag == ROUTING_NUMBER_TAG) 
{ 
    if ([Utility isValidRoutingNumber:textField.text]== NO) 
    { 
     [[iToast makeText:NSLocalizedString(@"Enter valid routing number", @"")] show]; 
     return NO; 
    } 
    else 
    { //save it 
     extension.payment.routingNumber = routingNumber.text; 
    } 
} 
else if (textField.tag == ACCOUNT_NUMBER_TAG) 
{ 
    if ([Utility isValidAccountNumber:textField.text] == NO) 
    { 
     [[iToast makeText:NSLocalizedString(@"Enter valid account number", @"")] show]; 
     return NO; 
    } 
    else 
    { //save it 
     extension.payment.accountNumber = accountNumber.text; 
    } 
} 
return YES; 
} 


- (void)textFieldDidEndEditing:(UITextField *)textField 
{ 

//I do nothing here except nulling out the 'activefield' var I use to autoscroll the uiscrollview as the user taps around from field to field 

} 



- (void)viewWillAppear:(BOOL)animated 
{ 
[super viewWillAppear:animated]; 

//reset the bool so that when they come back we're back to the 'normal' state and validation will again be checked in textFieldShouldEndEditing 

isDisappearing = NO; 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
[super viewDidAppear:animated]; 
} 


-(void)viewWillDisappear:(BOOL)animated 
{ 
TRC_ENTRY 
//set the bool to bypass validations in textFieldShouldEndEditing 

isDisappearing = YES; 
[super viewWillDisappear:animated]; 
} 

回答

2

除了消息顺序明确定义或名称强烈隐含的情况外,应避免依赖于任何特定顺序。例如,对于任何给定的视图,您可以合理地预期在调用-viewDidAppear之前调用-viewWillAppear,但不要指望以任何特定的顺序调用某个视图的-viewWillAppear,这些顺序与发送到不同视图的任何消息有关。

如果您需要帮助了解如何实施特定功能而不依赖于订单,请询问。但是,除非调用顺序记录在案或从方法名称明显可见,否则不要指望特定的顺序。

更新:我不明白到底发生了什么错在您添加的代码,但也许一些建议将帮助:

  1. 是您isDisappearing变量视图控制器的实例变量,一个全局变量,还是什么?如果它是一个实例变量,找出它是如何改变的。如果它是一个全局变量,那么......不要这样做。

  2. 请确保您注意到warning in the docs的效果是-textViewShouldEndEditing:只是建议性的,并且无论您返回什么内容,该视图都可能会停止编辑。

  3. 尝试暂时删除iToast的东西。如果事故仍然发生,至少你已经消除了这个问题的根源。如果停止发生,您将缩小搜索范围。

  4. 确定崩溃的原因。 (这真的应该是名单上的第一名。)崩溃不仅发生在神秘的地方 - 它的发生是有原因的。找到原因,你完成了85%。从发生崩溃时检查堆栈跟踪开始。如果这样不能提供足够的线索,请在引起崩溃的行之前的某个位置放置一个断点,然后开始步进,直到崩溃。如果一切都失败了,开始记录消息来追踪执行并监控你的假设。

  5. 你的视图控制器A在-viewWillAppear方法中做了什么?这可能是问题的一部分吗?你可以将代码移动到-viewDidAppear吗?

+0

只是意外地提出我的意见过早。让我再试一次......我的问题似乎是UITextFieldDelate相关事件以意想不到的方式发射。我确信有一个合乎逻辑的原因,但在某些情况下,textFieldShouldEndEditing * only *在UITextField具有焦点时单击NavController“返回”按钮时触发。我的代码在这种情况下工作。我刚刚发现textFieldDidEndEditing也在我遇到问题的情况下发射。我现在试图弄清楚为什么DID在这个特定的情况下发射,但不是其他人。 – jaySF 2012-03-06 01:15:56

+0

@jayboston'-textFieldShouldEndEditing:'应该在文本字段即将放弃其“第一响应者”状态时调用。因此,如果您点击不同的文本字段,或者执行其他任何可以使文本字段不再成为第一响应者的地方,则应该调用当前的焦点文本字段。这显然包括点击“后退”按钮,因为这将取代大部分响应者链,包括第一响应者。当文本字段确实停止为第一响应者时,你有没有调用'-textFieldDidEndEditing:'不* *的情况? – Caleb 2012-03-06 01:43:28

+0

@jayboston此外,请记住,如果您有多个具有相同代表的文本字段,该对象将接收所有文本字段的消息。所以你可能会得到一个字段的“-textFieldShouldBeginEditing:”和一个不同的字段或其他组合的“-textFieldDidEndEditing:”,而不一定按照这个顺序。密切关注'sender'参数。 – Caleb 2012-03-06 01:46:28

0

尝试在视图B之前viewWillDisappear做[self.youTextField resignFirstResponder]

0

这可能不是你的问题直接相关,但如果你觉得自己不完全理解的观点一辈子,我建议看看这里:What is the process of a UIViewController birth (which method follows which)?

这是一个很好的解释。

+0

谢谢。我对视图生命周期非常了解。我遇到的问题似乎是textField事件发挥作用的时候。我正在使用UITextFieldDelegate并在这些事件中处理了很多字段验证 – jaySF 2012-03-06 01:10:33

相关问题