And intersting behaviour can be observed when presenting a view controller from tableView:didSelectRowAtIndexPath:. It may take long seconds before the new view will be presented. This problem does not seem to be new and is already reported on openradar for iOS8.1, but comments and my own tests indicate that the problem persists even in iOS9.3.3 (build 13G34).

Two workarounds are to be known:

  1. Wrap the presenting of a controller in a dispatch_async call on the main queue.
  2. Use [self.tableView deselectRowAtIndexPath:indexPath animated:NO]; before presenting the view controller.

Below is an example with dispatch_async:

dispatch_async(dispatch_get_main_queue(), ^{
        UIAlertController* alert = [UIAlertController 
               alertControllerWithTitle:@"Message"
                                message:@"I have shown up immediately :)"
                         preferredStyle:UIAlertControllerStyleAlert];

        UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK"
                                  style:UIAlertActionStyleDefault
                                handler:^(UIAlertAction * action) {}];

        [alert addAction:defaultAction];
        [self.navigationController presentViewController:alert animated:YES completion:nil];
        alert.view.tintColor = [UIColor darkGrayColor];
    });

BTW: in the code above you see changing the alert’s button text color via the tintColor property. It has to happen after an alert controller is presented or the setting of the caller will have no impact.