views:

2265

answers:

2

I am trying to create a table view similar to the YouTube video uploader view in the Photo Gallery on the iPhone.

Here's the basic setup.

I have a custom UITableViewCell created that contains a UITextField. Displaying the cell in my table works great and I can edit the text with no problems. I created an event hook so I can view when the text has changed in the text field.

[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]

What I want to do is this. When the user first edits the text I want to insert a new cell into the table view below the current cell (newIndexPath is calculated prior to the proper position):

[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationBottom];
[self.tableView endUpdates];

Problem is when I run the cell insert code the cell is created but the text field's text updated briefly, but then the keyboard is dismissed and the text field is set back to an empty string.

Any help would be awesome! I've been banging my head about this one all day.

- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
    if (section == 0)
        return 2;
    else
        return self.tags.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    ...
    cell = (SimpleTextFieldTableCell *)[tableView dequeueReusableCellWithIdentifier:tagCellIdentifier];

    if (cell == nil)
    {
        cell = [[[NSBundle mainBundle] loadNibNamed:@"SimpleTextFieldTableCell" owner:nil options:nil] lastObject];
    }

    ((SimpleTextFieldTableCell *)cell).textField.delegate = self;
    ((SimpleTextFieldTableCell *)cell).textField.tag = indexPath.row;
    ((SimpleTextFieldTableCell *)cell).textField.text = [self.tags objectAtIndex:indexPath.row];
    [((SimpleTextFieldTableCell *)cell).textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
}

- (void)textFieldDidChange:(id)sender
{
    UITextField *textField = sender;

    [self.tags replaceObjectAtIndex:textField.tag withObject:textField.text];
    if (textField.text.length == 1)
    {
        [textField setNeedsDisplay];
        [self addTagsCell];
    }
}

- (void)addTagsCell
{
    NSString *newTag = @"";
    [self.tags addObject:newTag];

    NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:self.tags.count - 1 inSection:1];
    [self.tableView beginUpdates];
    [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationBottom];
    [self.tableView endUpdates];
}
A: 

Only thing i can think of here is that perhaps when you insert a row the whole table view is reloaded, if you did not add your cell properly to the cell queue, they wont come back in the state that they were , therefore you are seeing empty cells as a result of the insert, just a guess, hope it helps.

Daniel
I'm using a cell created with interface builder so it doesn't run through the initWithStyle:reuseIdentifier. Could that be a problem?
Colin
I just double checked and the identifier I'm using to dequeue the cell is the same one I assigned to the cell in IB.
Colin
are u using the same identifier for all your cells? this will cause problems
Daniel
There are 3 different types of cells I'm using and each has its own identifier.
Colin
what do you mean by types? If you have 20 cells you should have 20 different identifiers
Daniel
the above comment is assuming that each cell has its own state (meaing each cell contents can potentially be diffrent) if you are having users type in each cell then each cell can have its own state
Daniel
My table has 2 sections, 3 rows total. The first two rows are populated by an external table and a UIPickerView control. It's just the 3rd cell that is populated by direct user input via the text field.
Colin
I see what you're saying with the cell state. I have a workaround which works great but doesn't explain why things weren't working before. I now have a row at the bottom of the section in question that, when clicked, adds a new Tag row. This works great with no state issues. It seems like the problem was running the insertRowsAtIndexPaths: method during a text change event on the UITextField.
Colin
A: 

Quick update:

Shouldn't matter but I notices you don't need:

[self.tableView beginUpdates]
[self.tableView endUpdates]

since you are performing one operation. Not sure if that matters (it shouldn't).


Update:

I should have said that such issues are pretty common. Here is a post related to your issue

http://www.bdunagan.com/2008/12/08/uitextview-in-a-uitableview-on-the-iphone/

Also, others have abstracted this out. Specifically I have tried this with no such issues:

http://furbo.org/2009/04/30/matt-gallagher-deserves-a-medal/

You could use: http://github.com/joehewitt/three20/

But it has a bit of a learning curve.

Another Stackoverflow question tackling this issue:

http://stackoverflow.com/questions/376372/editing-a-uitextfield-inside-a-uitableviewcell-fails

Excuse me not answering your issue directly, but I think that the solution might be contained in one of these links.


Original Answer:

Try:

[newTextField setNeedsDisplay];

Sometimes the tableviews can be "sticky" with updating UITextView/UITextField content.

If that doesn't work, be sure that you're backing model is also updated properly. You haven't displayed any code indicating you updated the model (although I assume you did, otherwise it would have likely thrown an exception).

Corey Floyd
I tried calling setNeedsDisplay to no avail. I adding the method implementations to my original post, including model updates.
Colin
Ah, I think you're right about the beginUpdates and endUpdates calls. I thought the animation only occurred if the insert rows method was called within there, but it looks like that's just for groups of inserts and deletes.It's odd, since the UITextField in the UITableViewCell works fine by itself. No issues at all. It's just the inserting of a cell within a UITextField changed event that's causing the issue.Funny you should mention Three20. I'm actually using it for the majority of this app. There were some places that manually creating the table made more sense, this being one of them.
Colin