textFieldShouldEndEditing多次调用

时间:2010-06-25 21:04:46

标签: ios iphone objective-c uitextfield uitextfielddelegate

我正在处理一个包含多个UITextField个对象的视图。我的视图控制器用作UITextFieldDelegate,我已经实现了(BOOL)textFieldShouldEndEditing:(UITextField *)textField方法来保存和验证正在显示的记录。

如果用户在编辑项目后单击“完成”按钮并且保存/验证失败,则会显示UIAlertView,并且用户将保留在验证失败的UITextField上。< / p>

我的问题是这样的 - 当用户从UITextField点击保存/验证失败到另一个UITextField时,会多次调用(BOOL)textFieldShouldEndEditing:(UITextField *)textField方法,并UIAlertView多次弹出。

为什么当用户点击键盘上的“完成”时调用(BOOL)textFieldShouldEndEditing:(UITextField *)textField一次,但当用户点击另一个UITextField时多次调用?

这是我的代码:

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
    NSLog(@"textFieldShouldEndEditing called by textField with text=%@", textField.text);

    currentItem.nameOrNumber = nameOrNumber.text;

    // Try to save the managed object.
    NSError *error = nil;
    if (![[currentItem managedObjectContext] save:&error]) {        
        UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Uh Oh!",@"")
                                                             message:[error localizedDescription]
                                                            delegate:self
                                                   cancelButtonTitle:NSLocalizedString(@"OK",@"")
                                                   otherButtonTitles:nil];
        [errorAlert show];
        [errorAlert release];
        shouldEnd = NO;
    }

    return shouldEnd;
}

4 个答案:

答案 0 :(得分:4)

我认为您的问题来自于在编辑textField时直接点击另一个文本方法时调用textField方法的顺序。

如果我没有记错的话,它应该是这样的(你在A上编辑并点击B)

    对于字段B
  • textFieldShouldBeginEditing
  • 对于字段A
  • textFieldShouldEndEditing
  • 对于字段A
  • textFieldDidEndEditing
  • 对于字段B
  • textFieldDidBeginEditing

因此,当您使用textFieldShouldEndEditing方法时,文本字段B已成为第一个响应者。因此,当您显示UIAlertView时,B会失去焦点,因此也会调用textFieldShouldEndEditing

当我想在textField开始编辑时引发视图时,这也是一个问题。我找到的解决方案是创建一个布尔类变量,指示我当前是否正在从一个textField切换到另一个textField。 我将其设置为TRUE中的textFieldShouldBeginEditingFALSE中的textFieldDidBeginEditing。当您在textFieldShouldEndEditing时,如果设置为TRUE,则表示用户直接点击了另一个textField。然后你只需要找到正确的方法来进行一次测试(也许shouldEndEditing应该返回false或者其他东西)。

答案 1 :(得分:1)

另一种选择是让UIAlertView伪造正确的验证并将纠正部分推迟到后一时间。像这样:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    double delayInSeconds = 0.;
    self.currentTextField.text = @"Something that won't trigger validation error";
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        // do what you need here
    });
}

答案 2 :(得分:0)

我认为每个测试区域被调用2次。 为什么?想想......也传给了我,让我头疼

你不能做这样的事

- (BOOL)textFieldShouldEndEditing:(UITextField *)txtField{

if(i_dont_know){
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title" 
                                                    message:@"Message"
                                                   delegate:self 
                                          cancelButtonTitle:@"Ok" otherButtonTitles: nil];
    [alert show];
    [alert release];
    return false;
}

return true;}

UIAlertView节目是否也试图重新编辑文本字段 并调用此函数“textFieldShouldEndEditing:”...

所以我解决这个问题的方法是在界面delaration中添加一个名为“shouldEndEditing”的成员变量,默认为true。 在“textFieldShouldEndEditing:”之后可以这样。

- (BOOL)textFieldShouldEndEditing:(UITextField *)txtField{

if(shouldEndEditing == false)
{
    shouldEndEditing = true;
    return false;
}

if(i_dont_know){
    shouldEndEditing = false;
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title" 
                                                    message:@"Message"
                                                   delegate:self 
                                          cancelButtonTitle:@"Ok" otherButtonTitles: nil];
    [alert show];
    [alert release];
    return false;
}

return true;}
祝你好运......

答案 3 :(得分:0)

你不能在每个textview中添加不同的标签,并检查textFieldShouldEndEditing中的标签吗?或者我错过了这一点?