USS1994
USS1994

Reputation: 614

IPhone UIActivityIndicator won't display until after process has completed

I've been researching this for a few days, but nothing I've found works.

Here's the desired process: User presses the enter button on a pop-up window -> ActivityIdicator appears -> saving process occurs -> ActivityIndicator disappears.

However, for some reason the ActivityIndicator does not show up until after the process is complete, rendering it completely useless.

I attempted to follow the process described here: UIActivityIndicator not working properly?

Here is the code for the pop-up window

-(void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    // the user clicked one of the Enter/Cancel buttons
    [self performSelector:@selector(DisplaySpinner) withObject:nil afterDelay:0];
    if (buttonIndex == 1)
    {
        [self performSelector:@selector(EnterButtonClicked) withObject:nil afterDelay:0];
    }
    else
    {
        NSLog(@"Name Cancel Clicked");
    }
    [NameField resignFirstResponder];
    }

Here is the code for the DisplaySpinner method:

-(void)DisplaySpinner{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];

    [self.view addSubview:loadingIndicator];
    [loadingIndicator startAnimating];

    [pool release];
}

The EnterButtonClicked Method contains the saving process. Despite running in seperate processes, The ActivityIndicator doesn't show up until after the process is complete.

Any suggestions?

Upvotes: 1

Views: 1164

Answers (1)

Srikar Appalaraju
Srikar Appalaraju

Reputation: 73718

The app doesn't update the screen to show the UIActivityIndicatorView until the main run loop regains control. If your processing task blocks the main thread, the no UI updates will take place until it is finished. You should do your processing asynchronously.

When a rotation event happens, the willRotate... and willAnimateRotation... methods are called in one pass through the main run loop. So you block on the method before displaying the activity indicator.

To make this work, you need to push the method task over to another thread. That method would call back to this view controller when the work is completed so the view can be updated. I would put show the activity indicator in the willAnimateRotation... method.

What you need to do is forcing the UIActivityIndicatorView to start displaying even though the run loop won't be ended. One way is -

[self performSelector:@selector(animation) withObject:nil afterDelay:0]

-(void)startSpinner
{
    NSAutoreleasepool *pool = [[NSAutorepleasepool alloc]init];
    [indicatorView startAnimating];
    [pool release];
}

So essentially, performSelector sets up a timer to perform the animation message on the current thread’s run loop. The timer is configured to run in the default mode (NSDefaultRunLoopMode). When the timer fires, the thread attempts to dequeue the message from the run loop and perform the selector. It succeeds if the run loop is running and in the default mode; otherwise, the timer waits until the run loop is in the default mode.

Please note that specifying a delay of 0 does not necessarily cause the selector to be performed immediately. The selector is still queued on the thread’s run loop and performed as soon as possible.

Upvotes: 3

Related Questions