2010年11月10日 星期三

[iOS] The best way to embed a UITextField in UITableViewCell

    Recently I was struggling in how to put UITextField into UITableViewCell in my application. The target is to let the user to edit text fields in a table and be able to scroll the table at the same time. The idea is very simple, but there comes some challenges if you just directly put a UITextField into a UITableViewCell:

    1. The keyboard presented up will hide the cell (and also the textfield) you choose -- you CANT see what you typed! Even you put scrollTocell method in the text field event handler, it still cant scroll to correct position due to the table does not auto resize itself.
    2. Texts inside the cells will disappear when the user scroll up and down when the keyboard is not resigned.

    Problem 1 is coming from the stupid behavior of iOS keyboard. The keyboard does not care whether it will hide something important. It just showed up.
    Problem 2 is due to the UITableView tends to release cells( and text field inside) automatically when they are out of screen. So if the application does not save the text field data before its releasing, you will loss what you have type. Moreover, because the application loss the pointer to the cell, any methods that trying to access such pointer will crash (like resignFirstResponder).

    After googling for a while, I found the most simplest solution:
   To solve problem 1, just subclass your view controller from UITableViewController UITableViewcontroller will help you doing the table frame resizing and auto scrolling. It will help you auto scrolling to the text field. So the keyboard wont hide. You can also register keyboard event handler and do the resizing yourself.
   To solve problem 2, I write a UITextFieldDelegate which intercept textDidChanged event and save the current string in text field into another data structure. Synchronzing view and model in MVC model can avoid data lossing.

   This instruction is very high level and not clear enough. I will post my sample code later if I have time.