UITextField inside UITableViewCell - method to prevent text reset

I have a UITableView high enough that it requires scrolling. The UITextField cell in the table contains a UITextField for user input of some text.

The standard way to create this can be to create and add a text field and add it to a cell created or processed in cellFOrRowAtIndexPath: However, this constant re-creation means that the text entered in the field is deleted when the cell scrolls and returns to the field of view.

The solutions that I have found so far suggest using the UITextField delegation to track the text as it changes and stores in iVar or in a property. I would like to know why this is recommended instead of the simpler approach that I use:

I create a UITextField in the init method of the UITableViewController and immediately save it to the property. In cellFOrROwAtIndexPath I simply add a pre-existing field instead of initializing a new one. The cell itself can be recycled without problems, but since I always use the same UITextField , the content is saved.

Is this a smart approach? What could go wrong? Any improvements (maybe I could still create a field in cellFOrROwAtIndexPath , but first check if the property is nil?)

+4
source share
3 answers

When you create cells in cellForRowAtIndexPath , you need to use one re-identifier for this first cell (i.e. cellId1) and another for the rest (i.e. cellId2).

If you do this when you get a cell for the first item by calling [tableView dequeueReusableCellWithIdentifier:@"cellId1"] , you will always get the same object and will not be reused by other cells.

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { MyCell *cell = nil; // Only for first row if (indexPath.row == 0) { static NSString *cellId1 = @"cellId1"; cell = [tableView dequeueReusableCellWithIdentifier:cellId1]; if (cell == nil) { cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId1]; } } else { static NSString *cellId2 = @"cellId2"; cell = [tableView cellId2]; if (cell == nil) { cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault cellId2]; } } // do whatever return cell; } 
+1
source

If there is only one UITextField, I agree that your approach will be better / identical compared to using UITextField delegation (I think).

However, suppose you want to “broaden” your view so that there are now about 7-8 or more text fields. Then, if you start using your approach, the problem will be that you will store 7-8 or more text fields in memory and maintain them.

In such a situation, the best approach would be that you only create as many text fields as visible on the screen. Then you create a dictionary that will support the content present in the text field (which you can get using the UITextFieldDelegate methods). Thus, the same text field can be used when the cell is reused. Only the values ​​will change and will be determined by the values ​​in the dictionary.

In rim, the minimum creation in cellForRowAtIndexPath that is called during each scroll of the table, and therefore creating a text field in cellForRowAtIndexPath can be expensive.

0
source
 #import "ViewController.h" #import "TxtFieldCell.h" #define NUMBER_OF_ROWS 26 @interface ViewController ()<UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate> @property (weak, nonatomic) IBOutlet UITableView *tablView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.tablView.datasource = self; //set textfield delegate in storyboard textFieldValuesArray = [[NSMutableArray alloc] init]; for(int i=0; i<NUMBER_OF_ROWS; i++){ [textFieldValuesArray addObject:@""]; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } #pragma mark - TableView Datasource - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { TxtFieldCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TxtFieldCellId" forIndexPath:indexPath]; cell.txtField.tag = indexPath.row; if (textFieldValuesArray.count > 0) { NSString *strText = [textFieldValuesArray objectAtIndex:indexPath.row]; cell.txtField.text = strText; } return cell; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return NUMBER_OF_ROWS; } #pragma mark - TextField Delegate - (void)textFieldDidEndEditing:(UITextField *)textField { [textFieldValuesArray replaceObjectAtIndex:textField.tag withObject:textField.text]; } 
0
source

Source: https://habr.com/ru/post/1333494/


All Articles