In my UITableView , I have a set of user cells that contain a UITextField . I found out (the hard way), which, apparently, leaves the current view (either by clicking on the new view controller or disabling the active view (“return”), my application will crash when the keyboard is still visible.
To hide the keyboard when the user is still editing the UITextField , but the view has been changed, I added [self.view endEditing:YES]; just before you click on the new view controller, as well as in the viewWillDisappear method.
Now my application only crashes 1 out of 5 attempts to hide the keyboard. Here, I probably learned about the reason for this: When a cell moves behind the scenes, it is destroyed / recycled, so it can be deleted again if necessary. This means that after my cell and the contained text fields go off the screen, send a message to resignFirstResponder (either manually or via [self.view endEditing:YES]; application will [self.view endEditing:YES]; . This is the reverse trace:
#0 0x012e309b in objc_msgSend ()
Now my question is: how do I properly hide the UITextField keyboard inside my UITableViewCell in all situations? (the table view disappears, the new view controller moves, the cell / text field moves off the screen, etc.)
Any help is much appreciated, I just can't get rid of the crashes!
Ill includes one more code:
1) Custom cell class:
Custom cell implementation:
#import "TextInputCell.h" @implementation TextInputCell @synthesize mainText; @synthesize textField; @synthesize numberFormatter; @synthesize type; @synthesize delegate; - (void) initDelegateWithType:(int)aType { self.type = aType; textField.delegate = self; } - (BOOL)textField:(UITextField *)aTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; { if (![string length] || type == tpText || (isnumber([string characterAtIndex:0]) && type == tpNumber)) { [self save:[textField.text stringByReplacingCharactersInRange:range withString:string]]; return YES; } char c = [string characterAtIndex:0]; BOOL isSep = [string isEqualToString:[numberFormatter decimalSeparator]]; BOOL isMinus = [string isEqualToString:@"-"]; NSRange sep; sep.location = NSNotFound; sep.length = 0; if ([aTextField.text length]) sep = [aTextField.text rangeOfString:[numberFormatter decimalSeparator]]; if (isMinus) { // allow '-' only if type is tpNumber and field is empty if (type != tpNumber) return NO; if ([aTextField.text length]) return NO; [self save:[textField.text stringByReplacingCharactersInRange:range withString:string]]; return YES; } if (isnumber(c) || ((type == tpDecimal || type == tpNumber) && isSep && sep.location == NSNotFound)) { // allow separator for decimal and number, but only if not in text already if (!isSep && sep.location != NSNotFound && type == tpDecimal) { // round after , (only for decimal type) NSString* text = [NSString stringWithFormat:@"%@%@", aTextField.text, string]; double num = [[numberFormatter numberFromString:text] doubleValue]; double res = ((int)(num / 0.5)) * 0.5; aTextField.text = [numberFormatter stringFromNumber:[NSNumber numberWithDouble:res]]; [self save:aTextField.text]; return NO; } [self save:[NSString stringWithFormat:@"%@%@", aTextField.text, string]]; return YES; } [self save:[NSString stringWithFormat:@"%@%@", aTextField.text, string]]; return NO; } - (void) save:(NSString*)text { UITableView* view = (UITableView*)[self superview]; NSIndexPath* index = [view indexPathForCell:self]; if (delegate) [delegate setNewText:text forIndex:index]; } - (BOOL)textFieldShouldEndEditing:(UITextField *)field { NSLog(@"should end"); // if ([field becomeFirstResponder]) // [field resignFirstResponder]; return YES; } - (BOOL)textFieldShouldReturn:(UITextField *)field { if (type != tpText && [field.text length] == 0) field.text = @"0"; NSLog(@"should return"); // if ([field becomeFirstResponder]) // [field resignFirstResponder]; return YES; } - (void) startEditing { NSLog(@"should return"); [self.textField becomeFirstResponder]; } @end
View a controller that contains 4 of these cells:
@implementation MailPrefController @synthesize menuItems; @synthesize mailTo; @synthesize mailCc; @synthesize mailBcc; @synthesize mailSubject; @synthesize mailBody;
An accident can be played by clicking on one of the cells with a UITextField , slide the cell off the screen (without hiding the keyboard), and then simply reject the table view (for example, return via the navigation controller).
Could this be caused by manually opening the keyboard when clicking on a cell? ( startEditing ). I do this, so the user does not need to hit the text box, but editing also starts when he, for example. selects the text label of the cell.