Web Views
Just as with iPhone's native Safari application, you can display web-based content in your own applications by using the UIWebView class. (In fact, Safari on the iPhone uses a UIWebView for display.)
Web views provide touch-based control for zooming in and out of pages, panning, and scrolling. Tapping links can load pages, and tapping in text controls will open a keyboard for data entry.
To display a web page in your application:
Just as with other views, you can add web views to your interface in the usual way:
CGRect webRect = CGRectMake(10,10,300,400); UIWebView *myWebView = [[UIWebView alloc] initWithFrame:webRect]; myWebView.scalesPageToFit = YES;
The scalesPageToFit property ensures that larger pages are zoomed out or in enough to fit correctly in the current frame as well as letting you zoom in and out in response to pinch gestures.
Use the loadRequest: method to load content into the web view, which takes an NSURLRequest object as its only parameter:
NSURL *url = [NSURL URLWithString:@"http://www.google.com"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [myWebView loadRequest:request]; [self.view addSubview:myWebView];
This would load the Google homepage (Figure 4.34).
Figure 4.34 A web view displaying the Google homepage.
If your page is taking a long time or you want to cancel loading, use the stopLoading method. You can also check the loading property to make sure the page is actually in the process of loading.
If you are building a web browser–type interface with Forward and Backward buttons, you can use the canGoForward and canGoBackward properties to determine whether your buttons should be enabled, and you can use the goForward and goBackward methods to navigate through the web view's page history.
Although there is no direct access to the page history, you can easily maintain history via the delegate methods mentioned in the "What's the status?" sidebar. Code Listing 4.27 shows the code updated to include an activity indicator when the page is loading.
Code Listing 4.27 Implementing a web view.
Running JavaScript
You can execute JavaScript in a web view by using the stringByEvaluatingJavaScriptFromString: method. For example, if you wanted to open an alert dialog box in your web view, write the following:
[webView stringByEvaluatingJavaScriptFromString:@"alert('Hello World!);"];
This lets you manipulate your web page's style sheet or DOM or even call existing JavaScript functions defined within the page itself. For example, to change the background color of your web page, you could write the following:
[webView stringByEvaluatingJavaScriptFromString:@"document.bgColor=\"#000000\";"];
To call the JavaScript function myFunction defined in the web page, you could use this:
[webView stringByEvaluatingJavaScriptFromString:@"myFunction();"];
For performance reasons, any JavaScript you call must execute fully within ten seconds and must be less than 10MB in size.
Loading local content and handling hyperlinks
You can also use web views to display local content, such as an .html file that ships in your application bundle. This makes web views handy for displaying content that mixes graphics with text or requires multiple text styles. (Remember that UILabels and UITextViews are restricted to only a single style per control.)
To load content from a local file:
Use the loadHTMLString:baseURL: method to load content contained in the resources folder of the application bundle:
myWebView.scalesPageToFit = NO; NSString *htmlPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"myPage.html"]; NSString *htmlContent = [NSString stringWithContentsOfFile:htmlPath]; [myWebView loadHTMLString:htmlContent baseURL:nil];
This time, scalePageToFit has been set to NO because you don't want the user to be able to zoom in and out of the web view as if it were a web page. Figure 4.35 shows the application with a hyperlink in the page.
Figure 4.35 A web view displaying some local content.
To prevent a user from tapping any hyperlinks in the document, you can set userInteractionEnabled to NO for the web view. This also disables the ability to scroll content that may be longer than the control can fit on the screen at once.
or
To disable links entirely, return NO from the webView:shouldStartLoadWithRequest:navigationType: delegate method.
To open a link in the native Safari application, you could write the following in the webView:shouldStartLoadWithRequest:navigationType: delegate method (Code Listing 4.28):
NSURL *pageURL = [request URL]; if ( ([[pageURL scheme] isEqualToString: @"http"]) && (navigationType == UIWebViewNavigationTypeLinkClicked )) [[UIApplication sharedApplication] openURL:pageURL]; return NO;
Code Listing 4.28 Capturing clicks on a web view.
Here you are trapping only http: links. Other link types, such as https:, would have no effect.