2

I'm working on an iOS application and have a UITableView containing text messages (a table cell for each message). When a new message arrives a new cell is added in the UITableView. At first I used a single UITableView section and added all cells under it.

All worked fine until I decided to change the scheme and use multiple sections with one row each (it was the cleanest way I found to enforce a space between the cells). The problem I have with this scheme is that every time I try to add a new cell I get this exception:

2015-09-30 11:48:35.659 restcomm-messenger[15069:489766] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/UITableView.m:1702

And I get it when [self.tableView endUpdates] is executed (see below for full code)

I have checked many SO answers in similar questions but I think I have done everything right. Here are the 'interesting' code sections:

New message arrives, update backing store and the insert row to table:

...
// update the backing store
[self.messages addObject:[NSDictionary dictionaryWithObjectsAndKeys:type, @"type", msg, @"text", nil]];

[self.tableView beginUpdates];
// trigger the new table row creation
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:[self.messages count] - 1]]
                      withRowAnimation:animation];
[self.tableView endUpdates];
...

Section and row count callbacks:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [self.messages count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}

Fill cell callback:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *type = [[self.messages objectAtIndex:indexPath.section] objectForKey:@"type"];
    if ([type isEqualToString:@"local"]) {
        LocalMessageTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"local-message-reuse-identifier" forIndexPath:indexPath];
        cell.senderText.text = [[self.messages objectAtIndex:indexPath.section] objectForKey:@"text"];
        return cell;
    }
    else {
        RemoteMessageTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"remote-message-reuse-identifier" forIndexPath:indexPath];
        cell.senderText.text = [[self.messages objectAtIndex:indexPath.section] objectForKey:@"text"];
        return cell;
    }
}

I would expect that to work. Remember that for the original scheme (1 section may rows), it works just fine :(

If you want more details, here's the full code for the related Table View Controller: https://github.com/Mobicents/restcomm-ios-sdk/blob/master/Lab/restcomm-messenger-debug/restcomm-messenger/MessageTableViewController.m

Any hints are welcome

Antonis

atsakiridis
  • 1,002
  • 5
  • 19

0 Answers0