patric.schenke
patric.schenke

Reputation: 972

UITableView no selection after insert/delete

I have a UITableViewController-subclass wired up in a storyboard. Upon selection, an editor for elements of the data is pushed. This editor has a "done"-button for new entries and a "delete"-button for existing entries. They're wired up as follows:

- (void)doneButtonClicked:(id)sender {
    [self setEditing:NO animated:NO];
    [self.navigationController popViewControllerAnimated:YES];
    [self.delegate taskDefinitionEditor:self didCreate:self.taskDefinition];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    switch (buttonIndex) {

        case 1:
            [self.delegate taskDefinitionEditor:self didDelete:self.taskDefinition];
            [self.navigationController popViewControllerAnimated:YES];
            break;

        default:
            break;
    }
}

The UIAlertView is a confirmation-dialog.
As you can see, the editor calls a delegate to inform it about new or deleted items. This would be the UITableViewController-subclass. I've used different orders of the delegate- and navigation-controller-calls in order to find out if that was the reason for my problem. It's not.

And finally, here is my problem:
When the screen returns to the table after such an insertion/deletion, the UITableView won't select any cell for a while or until scrolled.

I've tried scrolling the table-view manually in viewDidAppear, but it didn't help. I've also tried reloadData, poking the refreshControl, disabling and enabling userInteraction, allowsSelection and allowsSelectionDuringEdit.
I've spent several hours searching for other solutions on the web today but couldn't come up with anything that works.

For the sake of completeness, here are the delegate-methods:

- (void)taskDefinitionEditor:(id)sender didCreate:(TaskDefinitionEntity *)taskDefinition {
    //remote call
    [self.dataProvider createTaskDefinition:taskDefinition success:^(TaskDefinitionEntity *taskDefinition){
        NSMutableArray *mutableDefinitions = self.taskDefinitions.mutableCopy;
        [mutableDefinitions addObject:taskDefinition];
        self.taskDefinitions = mutableDefinitions;

        dispatch_async(dispatch_get_main_queue(), ^{
            [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:mutableDefinitions.count-1 inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
        });
    } failure:^(NSError *error){
        NSLog(@"error creating task-definition:\n%@", error);
        [self requestFailed:error showAlert:YES];
    }];
}

- (void)taskDefinitionEditor:(id)sender didDelete:(TaskDefinitionEntity *)taskDefinition {
    //remote call
    [self.dataProvider deleteTaskDefinition:taskDefinition success:^(void){
        NSMutableArray *mutableDefinitions = self.taskDefinitions.mutableCopy;
        NSInteger index = [self.taskDefinitions indexOfObject:taskDefinition];

        [mutableDefinitions removeObjectAtIndex:index];

        self.taskDefinitions = mutableDefinitions;

        dispatch_async(dispatch_get_main_queue(), ^{
            [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
        });
    } failure:^(NSError *error){
        NSLog(@"error deleting task-definition:\n%@", error);
        [self requestFailed:error showAlert:YES];
    }];
}

So they're basically just doing a remote call to the server, receive the updated object and insert/delete it into/from the table-view and data-source.

Upvotes: 1

Views: 167

Answers (2)

patric.schenke
patric.schenke

Reputation: 972

The problem was a cache-update that was running in the background. It contains a notification to inform the controller of updated data, which in turn reloads the tableView.

This reload was triggered in a background-thread and thus the UI remained unresponsive. I've fixed it with performSelectorOnMainThread.

I found that out by setting the debugger to watch the data-model-property of the controller.

Sorry for wasting your time, @MySpecialPurpose, and thanks for the suggestions.

Upvotes: 1

JiuJitsuCoder
JiuJitsuCoder

Reputation: 1876

Have you tried pulling the insertrows:/deleterows: method calls out of the dispatch queue?

Upvotes: 0

Related Questions