0

I have a UITableViewController that works perfectly fine except in the following situation.

I create and present a modal view controller as follows:

[self.tableView beginUpdates];
NSMutableDictionary *request_params = [NSMutableDictionary new];
InputViewController *inputController = [[InputViewController alloc] initWithParams:request_params 
    continuation:^(UIViewController * thisInputController) {  
      [self complete:request_params success:^() {  
        [self.navigationController dismissViewControllerAnimated:YES completion:nil];  
        [self.tableView endUpdates]; # Added in 
      } failure:nil];  
    } cancel:^{  
      [self.navigationController dismissViewControllerAnimated:YES completion:nil];  
    }];  
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:inputController];  
[self.navigationController presentViewController:nav animated:YES completion:nil]; 

InputViewController calls continuation when user presses 'Done' (rightBarButtonItem) and cancel when user presses 'Cancel' (leftBarButtonItem).

complete makes a network async call and calls the success block upon completion of the request.

In the happy path (ie continuation block is called), all is good. However, when the modal dialog is dismissed in the cancel block, the TableView gets completely hosed. The scrolling works, but only the cells that were already visible are present. Scrolling results in an empty UI. Delegate and Datasource seem to be set correctly, but they don't appear to be getting called at all.

Before Scroll After scroll

I have tried multiple things include using delegates instead, explicitly calling dismiss in the main thread etc. I am now at a loss on what to try.

Would really appreciate any clues on what I'm missing or even pointers as to what to try next.

I have seen

Both cases seem to be cases of data being out of sync with the view, but neither situation applies since things work if I take the happy path (where data does get changed in the table) and in the cancel path, I do not touch the data at all.

[UPDATE]: Also, my row actions no longer work. Before & in the happy path everything is good. After a cancel though, no more edit actions :-(

[UPDATE]: Added the missing beginUpdates, endUpdates calls, that identifies the problem.

gentwo
  • 113
  • 9
  • My guess is that it doesn't have much to do with NSURL delegates or modal view controller dismisses; it's somewhere else in your code. You should add the code where the tableView that doesn't work is being set up, presented, and maintained, since that is the problem. – Alex Feb 10 '16 at 15:51
  • @Alex, appreciate your thoughts. However, I highly doubt that (I most certainly could be wrong, I admit). This is because in the happy path (where data does get changed in the table's datasource), it works like a charm. It only fails when I simply cancel the modal controller. Also, I've edited the question, to add another bit of info. – gentwo Feb 10 '16 at 15:59
  • @Alex, One more reason I don't think that's the issue, is that I've added logs and breakpoints to all my delegate and datasource methods. None of them even get called. – gentwo Feb 10 '16 at 16:02
  • I can tell you for sure that tableView's do not break when you present a modal view controller on top of them, or make an NSURL request. How does your 'happy path' interact with the tableView that breaks? – Alex Feb 10 '16 at 16:04
  • 1
    @Alex, your comment challenged me to relook at my code to see why my happy path works and where my cancel path differs.. And found the answer (See below). So, thank you :) – gentwo Feb 10 '16 at 16:20

1 Answers1

1

@Alex was correct. tableView's do not break when you dismiss a modal view from on top of them.

However, they do behave quite strangely when you beginUpdates and forget to endUpdates. It turns out that when canceling, the dismissViewController is getting called, but the endUpdates wasn't.

Make sure your beginUpdates and endUpdates match up or the tableView will behave quite strangely.

gentwo
  • 113
  • 9