2010-06-25 37 views
5

Tôi đang làm việc trên một chế độ xem có nhiều đối tượng UITextField. Trình điều khiển xem của tôi đóng vai trò là UITextFieldDelegate và tôi đã triển khai phương thức (BOOL)textFieldShouldEndEditing:(UITextField *)textField để lưu và xác thực bản ghi đang được hiển thị.textFieldShouldEndChỉnh sửa được gọi nhiều lần

Nếu người dùng nhấp vào nút "Xong" sau khi chỉnh sửa mục và lưu/xác thực không thành công, thì UIAlertView được hiển thị và người dùng được giữ trên UITextField không xác thực.

Vấn đề của tôi là thế này - khi người dùng nhấp từ UITextField rằng sẽ thất bại tiết kiệm/xác nhận vào một trong những UITextField s, sau đó phương pháp (BOOL)textFieldShouldEndEditing:(UITextField *)textField được gọi là nhiều lần, và UIAlertView bật lên nhiều lần.

Tại sao (BOOL)textFieldShouldEndEditing:(UITextField *)textField được gọi một lần khi người dùng nhấp vào "Xong" trên bàn phím nhưng được gọi nhiều lần khi người dùng nhấp vào một số khác UITextField?

Đây là mã của tôi:

- (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; 
} 

Trả lời

3

Tôi nghĩ vấn đề của bạn xuất phát từ thứ tự mà các phương pháp TextField được gọi khi bạn đang chỉnh sửa một TextField và bấm trực tiếp lên nhau.

Nếu tôi không nhầm, nó phải là một cái gì đó như thế này (bạn đang chỉnh sửa trên A và gõ vào B)

  • textFieldShouldBeginEditing cho lĩnh vực B
  • textFieldShouldEndEditing cho lĩnh vực Một
  • textFieldDidEndEditing cho lĩnh vực Một
  • textFieldDidBeginEditing cho lĩnh vực B

vì vậy, khi yo u đang ở phương thức textFieldShouldEndEditing, trường văn bản B đã trở thành trả lời đầu tiên. Vì vậy, khi bạn làm cho UIAlertView xuất hiện, B mất tiêu điểm và do đó gọi số textFieldShouldEndEditing quá!

Điều này cũng là một vấn đề đối với tôi khi tôi muốn tăng lượt xem khi textField bắt đầu chỉnh sửa. Giải pháp mà tôi tìm thấy là tạo một biến lớp boolean cho biết liệu tôi hiện đang chuyển từ một textField sang một textField khác. Tôi đặt nó thành TRUE trong textFieldShouldBeginEditing và đến FALSE trong textFieldDidBeginEditing. Khi bạn đang ở trong textFieldShouldEndEditing, nếu được đặt thành TRUE, điều đó có nghĩa là người dùng đã trực tiếp khai thác trên một đối tượng văn bản khác. Sau đó, bạn chỉ cần tìm đúng cách để thực hiện các bài kiểm tra của bạn chỉ một lần (có lẽ nênEndEditing sẽ trả về false hoặc một cái gì đó).

0

Có vẻ đúng cho tôi được gọi 2 lần cho mỗi trường thử nghiệm. Tại sao? chỉ nghĩ về ... đã trôi qua với tôi cũng và làm cho tôi đau đầu

Bạn KHÔNG thể làm một số như thế này

- (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;} 

Đó có phải là chương trình UIAlertView cũng đang cố gắng từ chức biên tập của trường văn bản và gọi funcion này là "textFieldShouldEndEditing:" ...

Vì vậy, cách của tôi để giải quyết điều này là thêm một biến thành viên được gọi là "shouldEndEditing" trong giao diện delaration, là đúng por mặc định. Và sau khi "textFieldShouldEndEditing:" có thể giống như thế này.

- (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;} 

Chúc may mắn ...

1

Một lựa chọn khác là để cho các UIAlertView giả một xác nhận chính xác và hoãn phần chỉnh để một thời gian sau. Một cái gì đó như thế này:

- (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 
    }); 
} 
0

Bạn không thể thêm các thẻ khác nhau trong mỗi lần xem văn bản và kiểm tra thẻ trong văn bảnĐơn vịSẽ thay đổi? Hay tôi đã bỏ lỡ điểm?

Các vấn đề liên quan