2

I'm working on an iPhone/iPad app with a UISplitView. In the left panel, I have a table, and the cells all have "Show Detail" segues to a Navigation Controllers for the right panel.

I do some lengthy computation for the new view, after the user selects an option in the table, so I have a UIActivityIndicatorView that I start animating in "viewWillAppear". In viewDidAppear, I perform the computation, and then refresh the appropriate UI elements and stop the UIActivityIndicatorView.

This works as expected on the iPhone: User taps item in table, new view appears with not much to say (but a little activity indicator showing), then a second or two later it fills in with the right info.

On iPad, it just looks like the app freezes after tapping the item in the table. Then the data appears after a few seconds. (Doesn't help that my test iPad is a first-generation mini, so it's slower.) No activity indicator.

In debugging, what I find is that viewDidAppear is actually called before the view appears. Nothing happens to the display until the viewDidAppear method returns. I've seen this with a breakpoint, but I've also confirmed it without breakpoints, by placing NSLog statements at the beginning and end of viewDidAppear.

So this looks bad; I wonder if there's anything I can do to my Segue, View Controller, Navigation Controller, or Split View controller to get this to behave the way I want?

Thanks in advance...

Apollo Grace
  • 361
  • 3
  • 16

2 Answers2

3

I eventually got around this by adding a delayed computation. The basic situation of viewDidAppear appearing before the view appears is still annoying, but this workaround covers it.

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // Use delayed computation to get around "viewDidAppear" sometimes being called before view appears.
    [self.activityIndicator startAnimating];
    [self performSelector:@selector(delayedComputation) withObject:nil afterDelay:0.01f];
}

- (void)delayedComputation
{
    // (Perform lengthy calculations...)
    // (Refresh UI with results...)
    [self.activityIndicator stopAnimating];
}
Apollo Grace
  • 361
  • 3
  • 16
  • Facing the exact same issue, I used `showDetailViewController` on a `UISplitViewController`. So far delay as you have suggested seems to the only thing that works. Was just wondering if there are any other solutions. – user1046037 Apr 25 '18 at 10:21
1

You should do this asynchronously, your performance is being affected because the processes you do to render your data are rather large and protracted, what you need it is to do all this within

    //Show you spinner here
    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
        //Background Thread, your logic for get data
        dispatch_async(dispatch_get_main_queue(), ^(void){
            //Run UI Updates and hide spinner`enter code here`

        });
    });

and probably it would behave as you want.

jose920405
  • 7,982
  • 6
  • 45
  • 71