Loading URL with an UIActivityIndicator

Loading URL with an UIActivityIndicator
Loading URL with an UIActivityIndicator

In a previous tutorial, you have seen how to load URLs already listed in a UITableView. In this tutorial, i will be showing you how to easily use a loading indicator (UIActivityIndicator) when loading a heavy URL in the UIWebView

I will be using the latest Xcode version (Xcode 4.5) which includes the iOS SDK 6. I recommend you upgrade although i think it would be fine to work with previous version.

Open up Xcode, File menuNewProject, select the Single View Application as a template, give it a name like LoadingIndicator and make sure “Use Automatic Reference Counting option” is checked. Pick up a place where to save your project and hit Create button to finish.

setup project

Expand the Project Navigator and click on MainStoryboard.storyboard to open it in the storyboard editor.

From the Object library, drag a UIToolbar and a UIWebView into your UI to look like this:

Set UI

Double click on the toolbar button, and change its text to something relevant as shown above.

Now time to work on your objects, you will mainly manage 3 objects: a web view, an indicator and a button. So switch to ViewController.h and add the convenient declarations for them, as well as the IBAction method for the toolbar button. Your “ViewController.h” file should look like this:

[sourcecode language=”objc”]
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

//Declaring properties

@property(nonatomic, strong)IBOutlet UIWebView *webView;
@property(nonatomic, strong)IBOutlet UIBarButtonItem *loadUrl;//be aware, this is NOT a UIButton

@property(nonatomic, strong)UIActivityIndicatorView *activityIndicator;

//Fire this method when click on the toolbar button
-(IBAction)loadWebView:(id)sender;

@end
[/sourcecode]

The obvious reflex now is to synthesize all the properties declared above. But wait! one of the Xcode 4.5 great features is the automatic synthesize, so you just set @property and Xcode will automatically add the right @synthesize and instance variables for you. That’s cool, isn’t? 😉

P.S: Remember, this feature is only available on Xcode 4.5 (LLVM compiler 4.1), so if you still working with previous version, don’t forget to manually synthesize the properties (below @implementation directive).

Now time to connect the IBOutlets. Select “MainStoryboard.storyboard” to open it in the editor. Select the Connections inspector in the right, and from the Outlet panel, drag a click from loadUrl and webView to their respective controls in the editor.

Connect the outlets

Do the same for the IBAction method, in the Received Actions panel, drag a click from loadWebView method to loadUrl bar button.

Bind IBAction

Last thing, you need to tell the ViewController class to be the delegate of the UIWebView in order to implement some delegate protocol methods. So click on the UIWebView control, and from the Outlets panel in the right, drag a click from the delegate to the View Controller as shown below:

set the delegate

You done with storyboard, go back to “ViewController.m” file and add the following method:

[sourcecode language=”objc”]
– (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

//initialize the activity indicator

UIActivityIndicatorView *actInd=[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

//Change the color of the indicator, this override the color set by UIActivityIndicatorViewStyleWhiteLarge
actInd.color=[UIColor blackColor];

//Put the indicator on the center of the webview
[actInd setCenter:self.view.center];

//Assign it to the property
self.activityIndicator=actInd;

//Add the indicator to the webView to make it visible
[self.webView addSubview:self.activityIndicator];

}
[/sourcecode]

You just initialized the UIActivityIndicatorView and assigned it to the activityIndicator property. No need to do the same for the webview and the button since this work is already done on the storyboard editor.

You may wonder why we didn’t initialize the activityIndicator on the storyboard editor like the other controls. Well, we could do so though i guess setting things programmatically still better 🙂

You need also to implement two important delegate methods of the UIWebView protocol:

[sourcecode language=”objc”]
#pragma mark – UIWebViewDelegate Protocol Methods

– (void)webViewDidStartLoad:(UIWebView *)webView{

[self.activityIndicator startAnimating];
}

– (void)webViewDidFinishLoad:(UIWebView *)webView{

[self.activityIndicator stopAnimating];
}
[/sourcecode]

The first method, webViewDidStartLoad, let you know when the URL is starting loading. This is important in order to show and animate the activityIndicator simultaneously.

The second method is also important since it informs the delegate when does the URL finish loading, at that time, you should stop animating the activityIndicator.

Remember the IBAction method that you declared in the .h file and bound it in the UI? well, you need to implement the right code inside so that, when you click on the bar button, the URL gets loaded in the UIWebView object.

Go ahead and add it to your file:

[sourcecode language=”objc”]
-(IBAction)loadWebView:(id)sender{

[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.youtube.com/watch?v=xUAD0gguFXc"]]];
}
[/sourcecode]

Build your project to make sure everything goes fine and run it.

Here we go, click on the bar button, you should see the indicator while the video is loading 😉

P.S: The url is a bit heavy depending on your internet connection, so be patient 😉

Final result

You can download the source code of the project here.

I would love to hear from you 🙂

5 Comments

  1. Hi 🙂

    Actually I have put a UIActivityIndicator inside a UIWebView (not another UIActivityIndicatorView):
    [self.webView addSubview:self.activityIndicator];

    Since UIActivityIndicator and UIWebView are subclass of UIView, I choosed to add the activity indicator to the webview to manage its position according to the webview and not to the root view.

    Malek.

Comments are closed.