This post answers the following questions:
- How can I build navigation (Forward, Back, etc.) for my UIWebView?
- How do I know what page the Web view is currently showing / user is viewing?
- How can I build a full “History” feature for a UIWebView?
In the last post, we discussed the basics of implementing the UIWebView. Here, we’re going to move forward to deal with navigation issues relating to the UIWebView. When you implement a UIWebView, all that you get is a view that displays HTML content. There are no forward or back buttons, no history, etc. These all have to be implemented by you.
Start by dragging (or coding, if you’d prefer sans-IB) a UIWebView onto your view, but leave some room at the top for buttons. Then, drag 2 UIButtons onto the top of your screen, double click each, and set the text to Back and Forward. Create an outlet for each, as well as a function to receive the “press” event, Touch Up Inside.
IBOutlet UIButton *bBack, *bForward;
IBOutlet UIWebView *wWw;
...
- (void)dontTouchMe:(id)sender;

Assign the dontTouchMe: function to Touch Up Inside by right-dragging from the UIButtons to the View Controller (File’s Owner). Assign the View Controller to be the delegate for the UIWebView by the same action. Lastly, assign the outlets by the reverse drag.
Next, meet the stringByEvaluatingJavaScriptFromString: function. This handy function lets you evaluate any JavaScript of your choosing at any time on a given UIWebView. There also happens to be a JavaScript function to go back and to go forward.
Create your dontTouchMe: function as follows:
- (void)dontTouchMe:(id)sender {
if(sender == bBack)
[wWw stringByEvaluatingJavaScriptFromString:@"history.go(-1);"];
else if(sender == bForward)
[wWw stringByEvaluatingJavaScriptFromString:@"history.go(1);"];
}
Save and build, and your back and forward navigation are now functional!
If a simple back/forward aren’t enough and you’re looking to create a full browser history, you’ll need a way to figure out where the user is. You could use the same function we used above to detect the page a user is currently viewing. For example,
NSLog(@"%@", [wWw stringByEvaluatingJavaScriptFromString:@"document.location"]);
…will log to the console the address of the current page the user is browsing. However, this isn’t particularly useful to us, because we need to know when the user changes pages. We could call this function once a second and try to detect a change, but that would be a waste — there’s an easier way!
The UIWebView’s delegate can accept messages regarding a page change using the shouldStartLoadWithRequest: function. This function allows you to detect what page the user is trying to go to before the load actually happens, and you can even refuse the page change by simply returning NO.
Declare an NSMutableArray as a member variable and let the SDK know that your View Controller conforms to the UIWebViewDelegate protocol. In your header file:
@interface AppNameViewController : UIViewController<UIWebViewDelegate> {
NSMutableArray *aHistory;
...
Note the protocol within brackets.
Allocate and initialize the array in your viewDidLoad function:
aHistory = [[NSMutableArray alloc] init];
…and don’t forget to release the array when your View Controller is done with it.
Next, we’re going to implement the function we mentioned above:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
[aHistory addObject:[[NSString alloc] initWithString:[request.URL absoluteString]]];
return YES;
}
What we’ve done here is taken the URL out of the user’s request (absoluteString returns the full URL, including protocol and server), created a new string, and added it to our array. After, we return YES to allow the UIWebView to go to the new page. Your aHistory object now contains a full accounting of your browsing.
For a more real-world history, you’d probably also want to code such that if you push the back button, you don’t add another item to the history, but rather simply “go backwards” in the history. To do this, simply add an int member variable to keep track of your position within the history array, and then before adding a new object to the array, check to see if the previous object ([aHistory objectAtIndex:x-1]) is equal to the new request. If so, instead of adding the new object, simply decrement the counter.
This is a four-part series on the UIWebView — please check back for more if you’re looking to go deeper.
FourTen Technologies, Inc., is a leading US iPhone app development firm. For information on having FourTen build a custom mobile application for your company, visit www.fourtentech.com. Article written by Jonathan Corbett (President & CEO, FourTen). Contact: jcorbett@fourtentech.com.