I have this UITableView with custom cells that can get only predefined values, therefore I use a UIPickerView as their inputView. All is jolly good until I edit a field and
You can follow this approach, not the best, but it works:
// pass the responder to a temporary (hidden) textField
[_tmpTextField becomeFirstResponder];
// reload data
[_tableView reloadData];
// reloadData is definitely async...
// so pass the responder back in a timed op
double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[_textField becomeFirstResponder];
});
As mentioned by @Eiko, this works for me!
Update the cell in UIPickerViewDelegate's pickerView:didSelectRow:inComponent:
method:
- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
TableViewCell *cell = (TableViewCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:pickerView.tag inSection:0]];
/*
Update your cell here.
*/
// Reload TableViewCell will resign the PickerView, so we need to focus it back.
[self.tableView reloadData];
NSIndexPath* indexPath = [self.tableView indexPathForCell:cell];
NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil];
[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationNone];
[cell.textField becomeFirstResponder];
}
If you are facing this issue with a search bar, the following did it for me in iOS 6:
I use beginUpdate and endUpdate After end update, get the cell contains the textfield already has focus then make it first responder
self.tableView.beginUpdates()
self.tableView.reloadRows(at: [indexPath], with: .automatic)
self.tableView.endUpdates()
let newCell = self.tableView.cellForRow(at: indexPath)
newCell.textField.becomeFirstResponder()
Swift solution:
we can override default canResignFirstResponder by subclassing UITextfiled
class CustomField: UITextField{
var canResign:Bool = false
override var canResignFirstResponder: Bool{
return canResign
}
}
all you need to set canResign variable before and after reload statement.
cell.offerInputTextField.canResign = false
tableView.reloadData()
cell.offerInputTextField.canResign = true
don't forget to assign the custom class text field as CustomField.
I met the same problem, none of the answers above worked perfectly (I see the keyboard bouncing up and down, etc.).
Following this SO post I fixed the issue by calling
[tableView beginUpdates];
[tableView endUpdates];
this worked for me, table rows get updates and even expand/shrink (if you are changing rows height dynamically) with a nice animation, all without resigning first responder or even starting keyboard dismiss.
This will not scroll your table view to fit any expanded row, so I put the snippet above in dedicated method, f.e.:
- (void)tableView:(UITableView *)tableView reloadRowWhileShowingKeyboard:(NSIndexPath *)indexPath
{
[tableView beginUpdates];
[tableView endUpdates];
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}