wan wan - 1 month ago 12
Objective-C Question

Tableview [cell.contentview viewwithtag:] is returning nil

I have a tableview with four sections first section has 7 rows in that first six rows has a textfield and the last row has two textfields

Section 1

t1

t1

t1

t1

t1

t1

t1 t2


section 2

t1 t2

t1 t2 // second row textfields are placed in fourth rows

t1 t2

t1 t2 // fourth row textfields are placed in someother rows

t1 t2

t1 t2

t1 t2


section 3

t1 t2

t1 t2

t1 t2

t1 t2

t1 t2

t1 t2

t1 t2



section 4

t1

t1

t1

t1

t1

t1

t1

t1


Second & third section contains seven rows having two textfields each

Fourth section has eight rows containing one textfield in each row I have assigned unique tags to all the textfields

In textFieldDidEndEditing I am saving the contents to an array in appropriate index.

If I am scrolling the tableview after entering data in the textfield. Some textfield positions are changed (i.e.) textfield in the second row are placed in the third row similarly some rows are swapped.

I have created 5 cell identifiers one for the first six rows in section one, second for the last row in the first section and remaining three cell identifiers for the other sections.

When I scroll some times cell.contentview viewWithtag returns nil value for tag

I think this is the reason for wrong textfield in some rows.

How to rectify this problem?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

NSString *identifier;<bn>
UITableViewCellStyle style = UITableViewCellStyleDefault;<br>
BOOL selectable = NO;<br>

switch (indexPath.section)
{
case 0:
{
if(indexPath.row < 6)
identifier = @"firstsectionSixRows";
else
identifier = @"firstsectionLastRow";
break;
}
case 1:
identifier = @"secondsection";
break;
case 2:
identifier = @"thirdsection";
break;
case 3:
identifier = @"fourthsection";
break;

}

return [self createCellForIdentifier:identifier
tableView:tableView
indexPath:indexPath
style:style
selectable:selectable];

}


In createCellForIdentifier method

else if([identifier isEqualToString:@"secondsection"])
{
int TextTag = 8 + indexPath.row * 2;



UILabel *lblName = (UILabel*)[cell.contentView viewWithTag:10000];

lblName.text = [NSString stringWithFormat:@"G%d",indexPath.row + 1];

//NSLog(@"row = %d texttag = %d",indexPath.row,TextTag);

UITextField *txtFirst = (UITextField*) [cell.contentView viewWithTag:TextTag];

if([textFieldArray count] > 0)
{
if(![[textFieldArray objectAtIndex:TextTag] isEqualToString:@""])
{
if(txtFirst)
txtFirst.text = [NSString stringWithFormat:@"%@",[textFieldArray objectAtIndex:TextTag]];
else
NSLog(@"Textfield is nil \n tag = %d \n cell section = %d row = %d",TextTag,indexPath.section,indexPath.row);

}
}

UITextField *txtSecond = (UITextField*) [cell.contentView viewWithTag:TextTag + 1];


if([textFieldArray count] > 0)
{
if(![[textFieldArray objectAtIndex:TextTag + 1] isEqualToString:@""])
{
if(txtSecond)
txtSecond.text = [NSString stringWithFormat:@"%@",[textFieldArray objectAtIndex:TextTag + 1]];
else
NSLog(@"Textfield is nil \n tag = %d \n cell section = %d row = %d",TextTag + 1,indexPath.section,indexPath.row);
}
}
}

Answer

I had the same problem (weird text coming up here and there, textfields swapping contents and all).

What turned out to be my problem was the constant re-creation of UITableViewCells all the time I was scrolling the UITableView. I suspect your table view is very long, so it won't fit in one screen, so you can't get rid of scrolling. I also had UITextFields in my UITableViewCells.

What happened in my case was that, once a UITextViewCell disappeared from onscreen, it was deallocated (this happens in your case since you are using cell identifiers, I see). Next time it came onscreen, it will re-use a previous textfield with it's text and settings.

What I ended up doing was to check the amount of creation of UITextFields in the cells. These are now created ONCE and they stay static for the duration of the UITableViewCell, that is, I don't re-create the UITextFields every time cellForRowAtIndexPath is called.

Another problem I think you should watch out for is:

[UITableView cellForRowAtIndexPath:] 

..and..

[UITableViewDelegate tableView: cellForRowAtIndexPath:]

...are two different functions, behaving differently. I was calling the wrong one and that gave me a nil from [UIView viewWithTag:] later on...

Just my 2 eurocents.