Bill
Bill

Reputation: 3823

How to hide a UIPopoverController while a lengthy operation is to be performed?

After selecting an option from a popover controller, the delegate is informed that a selection has been made.

I want to dismiss the popover, have it removed from the screen, and display an activity indicator to the user.

Unfortunately, the code below the dismissPopover runs before the popover actually disappears, resulting in a long wait without anything appearing to be happening.

- (void)itemSelected:(int)option {

    [popController dismissPopoverAnimated:YES];

    activityIndicator.hidden = NO;
    [activityIndicator startAnimating];

    switch (option) {
        case 0:
            // Do something that takes some time
            break;

        case 1:
            // Do something that takes even longer
            break;
    }

}

What's the best way to return control back to the calling ViewController after dismissing the popover?

Upvotes: 2

Views: 459

Answers (2)

Husker Jeff
Husker Jeff

Reputation: 857

The problem is that when you change the UI, it doesn't happen instantly. The changes are actually queued up to occur next time the main event loop finishes. Since that usually happens right away, we usually don't have to worry about the difference. All UI updates happen on the main thread, and since your long operations are also on the main thread, the app never gets around to updating the UI until the long operations are done.

One solution would be to use Grand Central Dispatch to offload those operations to another thread, which will allow the main thread to continue executing (and the UI to continue updating) until the operation is done.

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);

dispatch_async(queue, ^{
    [self performReallyLongOperation];
});

dispatch_release(queue);

Upvotes: 2

Mick MacCallum
Mick MacCallum

Reputation: 130193

You can use UIPopOverController's delegate method popoverControllerDidDismissPopover to execute your code after the popover is done dismissing:

Header

<UIPopoverControllerDelegate>

Implementation

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
    activityIndicator.hidden = NO;
    [activityIndicator startAnimating];

    switch (option) {
        case 0:
            // Do something that takes some time
            break;

        case 1:
            // Do something that takes even longer
            break;
    }

}

Upvotes: 0

Related Questions