olexiy prokhorenko’s blog

olexiy prokhorenko’s blog

Olexiy Prokhorenko  //  I wear many hats and like different things. Dream and evolve, explore what else I can do. I want to build something nice.

More about me you can find on my profile page. You can follow me on Twitter @alexeypro or connect with me on LinkedIn. Do you know me personally? Help me improve, rate my skills on PlusRated.

My interests: Mobile and Web, Technology, Entrepreneurship, Startups, Business, User Experience and Human Interfaces, Lean and Agile Methodologies, Self-improvement.

Mar 14 / 6:28pm

this is how we make UIActivityIndicatorView work #iphone #sdk #objective-c (tiny tutorial)

To begin with - I think it's necessary to mention that I am not an expert in Objective-C, neither in iPhone SDK. I had some experience developing for mobile devices (Siemens, to be precise) like 8 years ago, and that was fun, but obviously it was nothing comparing to what apps nowadays can do.

This was an intro and disclaimer. 

But this post is about UIActivityIndicatorView and how we can make it work in our app. If you Google for this information you will find tons of questions and problems with this thing. It's simple, just not that straightforward. I had to spend quite some time gathering all pieces from different resources to make it work, and later, to tweak to work in different situation. So, information described here will help you to get over those complications faster than I did.

So, let's start. UIActivityIndicatorView is just a view (right, this rollin gear is just a view), so general idea is that we want to show it whenever our application is doing some time consuming operations. Good habit to let user know that he is not left alone, just on "hold". :-)

Let's do it this way -- starting from our controller's .h file (same example on http://pastie.org/869669):

...

@interface RootViewController : UIViewController {

UIActivityIndicatorView *cLoadingView;

}

@property (nonatomic, retain) UIActivityIndicatorView *cLoadingView;

- (void)initSpinner;

- (void)spinBegin;

- (void)spinEnd;

@end

...


Simplest case possible. We have three methods defined here. One is for initialization, and we will call it when controller will just load; other two to start and stop spinning. Easy, so our controller's .m file will look like this (again, on http://pastie.org/869680):


 

...

@implementation RootViewController

...

@synthesize cLoadingView;

...

- (IBAction)doSomethingComplexAndTimeConsuming {

// this is how we start spinning

[NSThread detachNewThreadSelector: @selector(spinBegin) toTarget:self withObject:nil];

...

// TODO: something very complex and time consuming

 

// you can also add extra wait for the test (just uncomment line below)

//[NSThread sleepForTimeInterval:3];

 

...

// stop waiting...

[NSThread detachNewThreadSelector: @selector(spinEnd) toTarget:self withObject:nil];

...

// TODO: continue with our application

}

...

- (void)initSpinner {

cLoadingView = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease];    

// we put our spinning "thing" right in the center of the current view

CGPoint newCenter = (CGPoint) [self.view center];

cLoadingView.center = newCenter;

        [self.view addSubview:cLoadingView];

}

...

- (void)spinBegin {

[cLoadingView startAnimating];

}

...

- (void)spinEnd {

[cLoadingView stopAnimating];

}

...

- (void)viewDidLoad {

[self initSpinner];

[super viewDidLoad];

}

...

 

@end

...


Simple, isn't it? That really is trivial, and I thought most of the cases can be handled the same way. Unfortunately, when I wanted it to works fancier (I wanted the spinning gear to be in the navigation bar of my app) -- it brought me confusion on how this can be done. Just positioning up there? That's a pain, and I never was able to make it work (frankly speaking :-). However, then, I realized other thing. Navigation bar has buttons! So, why wouldn't we make our spinning gear a button? and this is what I did. It was really easy to do -- just tweaking our initSpinner method a little bit (on http://pastie.org/869703):

 


...

- (void)initSpinner {

cLoadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];

UIBarButtonItem *activityButton = [[UIBarButtonItem alloc] initWithCustomView: cLoadingView];

self.navigationItem.rightBarButtonItem = activityButton;

}

 

...


Simple. It's all looks pretty simple when there is a working example, isn't it? :-)


To crown it all, I would love to mention that Apple actually worked hard on making deep documentation available. And while they certainly limit developer with UI requirements and restrictions, they allow to build beautifully helpful and looking application very fast.



 

 

6 comments

Jul 20, 2010
SS said...
Hi, thanks for the code. Im just a bit confused how to tie this in with existing viewcontrollers. Basically a user selecting a cell in a tableview and then having the activity indicator appear between that and the actually second view controller draws.

thank you.

Aug 04, 2010
Ted S said...
Many thanks brother ... this drove me crazy for hours. Your code is straight forward and ran as expected on the first go.

Cheers,
Ted S

Aug 04, 2010
I am glad it helped. Want to rate me? http://www.plusrated.com/u/alexeypro Thanks
Aug 09, 2010
charlie-gilberto said...
Hi..
thanks for the code,,
your code helpful for my problem

rgrds

Aug 19, 2010
Peto said...
Thanks a lot You're the man
Aug 19, 2010
Stella said...
How to make UIActivity bigger? thanks

Leave a comment...