views:

6996

answers:

8

It seems like a pretty simple problem, but I have been unable to find any good answers.

What I'm trying to do is to make some sort of animation while some function is loading. I have already included an animated .gif file in the webapp when waiting for content, but I need the same functionality when navigating in native. For instance, when I press a button in the tab bar, the screen is just blank until the entire page is loaded.

It doesn't need to be anything fancy. I like the way this is solved in the facebook app with the infamous "spinning wheel" for instance.

Thanks in advance!

+1  A: 

I guess it depends on what is being loaded? Are you waiting for a response from a server? In that case I usually put a spinning wheel (UIActivityIndicatorView) on my view that has the hide when not animating checkbox checked (there is a message to set this programmatically as well). Then when the data is received from the server I simply call stopAnimating on the UIActivityIndicator view and it will hide. You can then show whatever it is you need to show.

quadelirus
Seems like just the thing I was looking for. Do you have some example code of this? (Still a bit rusty in Objective-C)
Christer-André Larsen
If you have a view controller in interface builder just make it subclass your own UIViewController subclass. Then add an IBOutlet UIActivityIndicatorView to the view. let's say IBOutlet UIActivityIndicatorView indicator; You would then simply call [indicator startAnimating] or [indicator stopAnimating]; (I think that is the right name for the message.
quadelirus
Ahh sorry, I didn't specify that, but I'm not using IB. The app is nearly finished, so I would rather not start using it at this point :)
Christer-André Larsen
+1  A: 

You can add a UIActivityIndicatorView to whichever view is "loading":

CGRect mainBounds = [[UIScreen mainScreen] bounds];
CGRect indicatorBounds = CGRectMake(mainBounds.size.width / 2 - 12,
    mainBounds.size.height / 2 - 12, 24, 24);
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc]
    initWithFrame:indicatorBounds]];
indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
[indicator startAnimating];
[yourLoadingView addSubview:indicator];
Nathan de Vries
I manage to add the indicator, but sadly not when I'm supposed to. What I'm try to do is making this indicator appear when moving from one page to another (when making a new ViewController and requesting a new page with NSURLRequest). I've tried to test on webView.loading and then start the animation when this is true, but nothing happens. The screen is still just white until the new page is loaded (and yes, I've tried with a background color so it is visible)...
Christer-André Larsen
+8  A: 

you can add an UIActivityIndicatorView as a subview to a view and when the action is over you can remove it from superview...

UIActivityIndicatorView  *av = [[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease];
av.frame=CGRectMake(145, 160, 25, 25);
av.tag  = 1;
[yourView addSubview:av];
[av startAnimating];

removing it

UIActivityIndicatorView *tmpimg = (UIActivityIndicatorView *)[yourView viewWithTag:1];
[tmpimg removeFromSuperview];

hope it helps...

SorinA.
+1  A: 

On an aesthetic note, notice that UIActivityIndicatorView comes with several built-in styles for you to choose from. The code examples above use the Gray and White options, but there are several more described in Apple's documentation. You can set the style by using:

-initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyle)

or by setting the object's 'activityViewIndicatorStyle' property.

thauburger
A: 

I'm trying to do this as well, and I am using IB.

In my case the NIB is tied to a UITableViewController. The NIB has a UIView tied to a topView property, and within that is a UITableView tied to a tableView property (and also the view property ... IB doesn't expose tableView but it does expose view, and then both are set to the same thing once you're off and running).

My latest game plan was to programmatically create a UIView with a black background and a centered UIActivityIndicatorView (large white). I would then add this as a subview of my topView. Then, when I was finished, I'd fade the UIView view out and remove it, exposing whatever view was awaiting beneath it.

I'm not too happy that I have to create a topView, but I'm following a suggestion from this Stack Overflow thread, and trying to make it work that way. Alas, it's not displaying. :(

Even though the view is being created and added as a subview (plus it's opaque and alpha is set to 1.0), it's as if it's not even there. I even tried moving it to the front of the z-order. No dice.

Also, just to clarify: Yes, the table view is being loaded via a separate thread (NSOperation, etc.).

Joe D'Andrea
+2  A: 

Ah-ha! I've just stumbled upon a most handy class: MBProgressHUD. Give it a try. I do believe it does what you seek, and then some.

I've also contributed a few mods in the author's blog post comments.

Joe D'Andrea
Thank you! It seemed quite useful. I'll give it a try...
Christer-André Larsen
+1  A: 

You need to implement a new thread for the work that needs to be done between the start and the stop of the animation. See following:
http://discussions.apple.com/thread.jspa?threadID=1531358&start=0&tstart=0

Brij
+1  A: 

Your issue will be that the activity indicator will not be displayed because it will only be shown on the next pass through the run loop - by which time you will have done everything you need to!

The very very very easiest way of doing this is to move your code to call the next view into its own method then (having built a UIActivityIndicator as per other posts here) do

[self.myactivityindicator startAnimating];
[self performSelector:@selector(myCodeToCallTheView) withObject:nil afterDelay:0];

this gives just enough of a chance for the indicator to be drawn before running your code to draw the view. Of course once your new view appears it will overwrite the selector.

Andiih