Himanshu Ingole Himanshu Ingole - 2 months ago 5
Objective-C Question

custom uitableviewcell with textfield disappearing

There is custom textfield cell which being added to tableview as per user input. Something similar to Contact book when user add multiple mobile numbers.
Nib is register with table view using below code.

[self.tableView registerNib:[UINib nibWithNibName:@"TextFieldTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:textFieldTableViewCellIdentifier];


The method which add dynamic cell:

-(void)addAccoladesValue
{
NSMutableArray *DataArray = [self.tableData[SectionTagAccolades-1][sectionDataKey] mutableCopy];
NSMutableArray *DataValueArray = [self.tableData[SectionTagAccolades-1][sectionDataValue] mutableCopy];
self.accoladesArray = self.accoladesArray ? self.accoladesArray : [NSMutableArray new];
TextFieldTableViewCell *accoladesCell = [self setupTextField:self.accoladesArray tag:TextFieldTagFirstName placeholder:@"Description" cellTextFieldIdentifier:textFieldTableViewCellIdentifier];
accoladesCell.hidden = NO;
[DataArray addObject:accoladesCell];
[DataValueArray addObject:@""];
self.tableData[SectionTagAccolades-1][sectionDataKey] = DataArray;
self.tableData[SectionTagAccolades-1][sectionDataValue] = DataValueArray;
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:SectionTagAccolades-1]] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:SectionTagAccolades-1]] withRowAnimation:UITableViewRowAnimationTop];
[self.tableView endUpdates];
}


Code seems to work expected but some times cell disappear and for few times it the newly added cell is getting added to top section which is wrong.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TextFieldTableViewCell *cell = (TextFieldTableViewCell*)self.tableData[indexPath.section][sectionDataKey][indexPath.row];
if ([cell isKindOfClass:[TextFieldTableViewCell class]])
{
cell.textfield.tag = indexPath.row;
cell.textfield.superview.tag = indexPath.section;
cell.textfield.text = self.tableData[indexPath.section][sectionDataValue][indexPath.row];

}
cell.hidden = NO;
[cell setNeedsUpdateConstraints];
[cell setNeedsLayout];
return cell;
}


What could you be possible reasons for this weird behaviour?

Answer

I can actually spot a lot of things that can potentially go wrong here. A couple of things.

1. Don't store TableViewCells

You should not store cells manually, the UITableView will take care of this for you. The UITableView will reuse cells that scrolls out of view to display new data, and can thus be associated with different objects.

In tableView:cellForRowAtIndexPath: call dequeueReusableCellWithIdentifier:forIndexPath: on your tableView to obtain a cell, and then populate it with the data it should display.

2. Data structure

Looks like your self.accoladesArray contains the data the should be displayed in the TextFieldTableViewCells. Why do you keep to references to this, one instance property and one in self.tableData?

If you would only keep the instance property your UITableViewDataSource methods would boil down to

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
   // accolades section
   return self.accoladesArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView 
     cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   // accolades section
   TextFieldTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: textFieldTableViewCellIdentifier forIndexPath: indexPath];
   NSString * text = self.accoladesArray[indexPath.row];
   // custom setup
   return cell;
}

- (void) addAccoladesValue
{
    if (!self.accoladesArray) self.accoladesArray = [NSMutableArray new]; 
    [self.tableView beginUpdates];
    {
        [self.accoladesArray insertObject: @"" atIndex: 0];
        [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:SectionTagAccolades-1]] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
    [self.tableView endUpdates];        
}