0

I have a table populated with a mutable array. The cells are custom, with an UITextView, delegated on the customcellclass, which value I'd like to keep. It gets erased after every table reloadData.

Any idea about how to keep it? The ideas I had, and not able to go for:

  • Store the textView value on the same array which populates the table. From where? TextViewDidEndEditing? How to pass the value, and how to know which row was it?
  • Maintain an array of textViews apart from the other. Same problem of communicating cell-table and then I have to maintain this array also. Besides, I should take the textView away from the .nib. ...I don't came up with more know.

Any approach or help will be much appreciated. Thank you!

PS: I did lots of searches, most directing to forms, but this is a mutable array, I'll have undefined rows on the table.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";


GuiCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];


if (cell == nil) {
    NSArray* views = [[NSBundle mainBundle] loadNibNamed:@"GuiCustomCell" owner:nil options:nil];

    for (UIView *view in views) {
        if([view isKindOfClass:[UITableViewCell class]])
        {
            cell = (GuiCustomCell*)view;
        }
    }   
}

if (timesArray || [timesArray count]) {        

    TakenTime *time = [[TakenTime alloc] init];
    time = [timesArray objectAtIndex:indexPath.row];

    if ([timeFormat isEqualToString:@"seconds"]) {
        cell.detailTextLabel.text = [time stringTimeFormat2];
    } else {
        cell.detailTextLabel.text = [time stringTimeFormat1];
    }

    cell.detailTextLabel.font = [UIFont systemFontOfSize:25];
    cell.textLabel.font = [UIFont systemFontOfSize:18];
    cell.textLabel.textAlignment = UITextAlignmentLeft;
    cell.detailTextLabel.textAlignment = UITextAlignmentCenter;
    cell.textLabel.text = [NSString stringWithFormat:@"%i.",indexPath.row+1];        

}else{

    cell.textLabel.text = @" ";

}

[cell setDefaultText:TRUE];

return cell;

}

g10k
  • 53
  • 5

2 Answers2

2

Set cell.textLabel.delegate to self (your UIViewController), then in the textFieldDidEndEditing: method, you can retrieve the indexPath corresponding to the cell in which the UITextField is located this way:

-(void)textFieldDidEndEditing:(UITextField*)aTextField
{
    UITableViewCell* containerCell = (UITableViewCell*)aTextField.superview;
    NSIndexPath* indexPath = [self.tableView indexPathForCell:containerCell];
    // Store the text, for example in an NSMutableDictionary using the indexPath as a key
    [self.mutableDictionaryOfTextValues setValue:aTextField.text forKey:indexPath];
}

Of course, in your tableView:cellForRowAtIndexPath: method, you will retrieve the text value stored in [self.mutableDictionaryOfTextValues objectAtIndex:indexPath] and affect it to cell.textLabel.text to restore the previously typed text.

Don't forget to instanciate your NSMutableDictionary (self.mutableDictionaryOfTextValues = [NSMutableDictionary dictionary];) in your init method of your UIViewController or some place similar.


Note that this will only work if you end the edition of the UITextField before scrolling, that is when your UITextField receive resignFirstResponder (e.g. if you dismiss the keyboard, or the user click in another UITextField that will become the new firstResponder), because that's when the textFieldDidEndEditing: delegate method is called. If you want to store the text each time the user type a character or modify the text, without waiting for the user to go on another textfield and textFieldDidEndEditing: is fired, you can use the textField:shouldChangeCharactersInRange:replacementString: delegate method instead:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    // Compute the new text that we will obtain once the new character has been validated
    NSString* newText = [textField.text replaceCharactersInRange:range withString:string];
    // Store it in our dictionary. Same as before, but use newText instead of textField.text
    UITableViewCell* containerCell = (UITableViewCell*)aTextField.superview;
    NSIndexPath* indexPath = [self.tableView indexPathForCell:containerCell];
    // Store the text, for example in an NSMutableDictionary using the indexPath as a key
    [self.mutableDictionaryOfTextValues setValue:newText forKey:indexPath];
    // Accept the new character
    return YES;
}
AliSoftware
  • 32,623
  • 6
  • 82
  • 77
  • Everything seemed working very well but... the indexPath is returning me the same row/section every time, so it always stores the text in the same position. – g10k Sep 01 '12 at 19:29
  • Is the `containerCell` always the same instance too? and the `UITextField`? Did you try to dig a bit using the debugger? – AliSoftware Sep 01 '12 at 19:35
  • Excuse for the dumb question, but how to know if the containerCell is always the same instance? Breakpoint at UITableViewCell* containerCell = (UITableViewCell*)textView.superview; and then look where? – g10k Sep 01 '12 at 19:51
  • Yes, put a breakpoint right after the line and check if the address the `containerCell` variable points to is always the same (`containerCell` is always the same object) or not. You can also try using an NSLog to print the variable in the console (actually that's quite basic debugging you should be familiar with this) – AliSoftware Sep 01 '12 at 19:57
  • The address of the containerCell changes every reloadData of the table – g10k Sep 01 '12 at 20:34
0

This solution is assuming you assigned tags to your textfields,you can declare tags in the cellForRowAtIndexPath method:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:         (NSIndexPath *)indexPath {
//Code
// Configure the cell...
cell.myTextbox.tag = indexPath.row;
 }

You get your values at the textFieldDidEndEditing method:

-(void)textFieldDidEndEditing:(UITextField *)textField{

if ([textField.text isEqualToString:@""]) {
    textFieldContent[textField.tag] =@"";

}
textFieldContent[textField.tag] = textField.text;
}

Then you set the text in your cellForRowAtIndexPath method :

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:      (NSIndexPath *)indexPath {
 MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Mycell" forIndexPath:indexPath];


// Configure the cell...
cell.myLabel.text = [nombres objectAtIndex:indexPath.row];
cell.myTextField.tag = indexPath.row;
if([textFieldContent count] < indexPath.row){
    cell.myTextField.text = @"";

}
else{
if ([textFieldContent count] == 0) {
    cell.myTextbox.text = @"";

}
else{
    cell.myTextbox.text = [textFieldContent objectAtIndex:indexPath.row];
}

}

return cell;
}
Pugin
  • 346
  • 1
  • 6
  • 19