16

I have a TextView inside a UITableViewCell. The text inside the TextView can be edited right there in place.

The TextView grows and shrinks vertically depending on the number of lines the text contains. So far I haven't found a possibility to also let the row containing the TextView grow and shrink dynamically.

[tableView reloadData];

or

[tableView reloadRowsAtIndexPaths: withRowAnimation:];

don't work, because they dismiss the keyboard on every change.

Is there a way to change height of an individual row in a UITableView without dismissing keyboard?

Stefan
  • 1,051
  • 3
  • 11
  • 23

3 Answers3

39

Yes, you can have the row heights adjust as you type. It's not documented, and it defies reason, but all you need to do is set the new value in tableView.rowHeight (or have heightForRowAtIndexPath:ready to compute the new heights), then do this:

[tableView beginUpdates]; // updates the row heights ...
[tableView endUpdates]; // ... nothing needed in between
Jeff
  • 2,659
  • 1
  • 22
  • 41
  • Yes! Awesome! One caveat, though: It only works when I save the current text on every edit event from inside the TextView to the variable that fills the TextView on cell load. beginUpdates / endUpdates don't seem to access the exact same TextView object and text I am actually editing. – Stefan Apr 15 '11 at 08:03
  • Seems to work only for iOS >= 4.0 without the keyboard bouncing down and up, though. – Stefan May 09 '11 at 10:17
  • YAY! Thanks. It took me a while to find the right Google keywords, but you've saved me a lot of hassle. – Ben Challenor Mar 10 '12 at 21:22
  • This works equally well for when you need to add/remove a row without hiding the keyboard. Thanks! – grahamparks May 10 '12 at 20:31
  • this solution insistently moves tableview – coolcool1994 Jun 30 '17 at 22:42
1

The task is to invoke row height recomputation without cell reuse (to save current responder).

One can call moveRowAtIndexPath:toIndexPath: for the same indexPath right after height change

- (void)textInputTableView:(UITableView *)tableView cellHeightDidChangeForIndexPath:(NSIndexPath *)indexPath
{
    [tableView moveRowAtIndexPath:indexPath toIndexPath:indexPath];
}
malex
  • 9,874
  • 3
  • 56
  • 77
0

After reloadRowsAtIndexPaths the cell changes memory value, so if you call becomeFirstResponder just after the reloadRowsAtIndexPaths, you are trying to set as firstResponder the old cell, which does not exist (becomeFirstResponder returns false and keyboard exits).

The solution is to call again cellForRowAtIndexPath in order to get the new memory value of the reloaded cell, and then call becomeFirstResponder to that cell.

  • Right, thanks. Unfortunately this is still no solution for the original problem, since it makes the keyboard bounce down and up. The call to becomeFirstResponder, allthough it works your way, is too late, the keyboard already started to go away (due to the reloadRowsAtIndexPath I assume). – Stefan Apr 01 '11 at 07:52