I have following problem: I've got an UITableView with 7 custom cells. Each of these cells hold a label and an UITextField in it. Since the cells are somewhat big, you have to scroll down to see the last 3 cells. The problem is, as soon as I scroll down, the text in the textfields of the first 3 cells (those, that aren't visible then) gets removed. All that is left is the placeholder. The same goes for the last 3 cells, as soon as I scroll back up. The textfield in the 4th cell retains its text just fine, since its always visible. Does anyone have an idea how to solve this problem?
Best regards.
UPDATE: Here's the code for the corresponding comment:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"NewXYZTableCell";
NewXYZTableCell *cell = (NewXYZTableCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NewXYZTableCell" own开发者_高级运维er:nil options:nil];
for(id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[NewXYZTableCell class]])
{
cell = (NewXYZTableCell *)currentObject;
break;
}
}
}
switch (indexPath.row) {
case 0:
cell.myLabel.text = @"XYZ";
// and so on...
default:
break;
}
return cell;}
You probably use the dequeueing mechanism to populate the UITableView with its cells. This means that a cell that has been allocated and is currently off the screen can be reused and filled with other content. This saves you the performance costs of allocating a new cell for each row. So even table views with a lot of cells can perform very well, because it only has to deal with, say, six or seven cells at the same time.
And this probably is also what happens to you. Your cells get scrolled off the screen and are now free to be reused by the new cells coming to the screen (displaying different contents). So you will have another title and another (new) text field. So you need to save your input somewhere if a cell gets scrolled off the screen. For example, you can listen to a UITextFieldTextDidChangeNotification
.
Register your controller as an observer, e.g. in -viewDidLoad
:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChanged:) name:UITextFieldTextDidChangeNotification object:textField]
And then implement your method, in this case textFieldChanged:
, which takes an NSNotification*
as parameter and save your input:
-(void)textFieldChanged:(NSNotification *)notification {
...
}
Don't forget to reinsert the input to your cells if they are scrolled back on the screen.
Another option is to not use dequeueing and create all cells as soon as they are needed. This might be a better idea if you have only very few cells. You need to take care then to return the correct cell in -cellForRowAtIndexPath:
.
Posting this as new answer, so I can make use of code formatting.
My suggestion is to save the seven cells in seven instance variables and create the appropriate getters. So, in your .h file you declare the variables:
NewXYZTableCell *cell0;
...
NewXYZTableCell *cell6;
In your implementation, write a getter:
-(NewXYZTableCell*) getCellNumber:(int)cellNumber {
NewXYZTableCell *cell;
switch (cellNumber)
{
case 0:
cell = cell0;
break,
...
case 6:
cell = cell6;
break,
}
if (cell == nil){
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NewXYZTableCell" owner:nil options:nil];
for(id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[NewXYZTableCell class]])
{
cell = (NewXYZTableCell *)currentObject;
break;
}
}
}
return cell;
}
This getter will return the cell with the corresponding number after creating it, if it did not exist before. Then you can make use of it in -tableView:cellForRowAtIndexPath:
:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [self getCellNumber:indexpath.row];
}
精彩评论