Uiwebvie笔记 之初始化

NSString* path =
    [[NSBundle mainBundle] pathForResource:@"help" ofType:@"html"];
NSURL* url = [NSURL fileURLWithPath:path];
NSError* err = nil;
NSString* s = [NSString stringWithContentsOfURL:url
                  encoding:NSUTF8StringEncoding error:&err];
// error-checking omitted
[self.wv loadHTMLString:s baseURL:url];
 
 

Chapter 11. Web Views

A web view (UIWebView) is a UIView subclass that acts as a versatile renderer of text in various formats, including:

In addition to displaying rendered text, a web view is a web browser. If you ask a web view to display HTML that refers to a resource available on disk or over the Internet, such as an image to be shown as the source of an <img> tag, the web view will attempt to fetch it and display it. Similarly, if the user taps, within the web view, on a link that leads to content on disk or over the Internet that the web view can render, the web view by default will attempt to fetch that content and display it. Indeed, a web view is, in effect, a front end for WebKit, the same rendering engine used by Mobile Safari (and by Safari on OS X). A web view can display non-HTML file formats such as PDF, RTF, and so on, precisely because WebKit can display them.

As the user taps links and displays web pages, the web view keeps a Back list and a Forward list, just like a web browser. Two properties, canGoBack and canGoForward, and two methods, goBackand goForward, let you interact with this list. Your interface could thus contain Back and Forward buttons, like a miniature web browser.

A web view is scrollable, but UIWebView is not a UIScrollView subclass (Chapter 7); it has a scroll view, rather than being a scroll view. You can access a web view’s scroll view as itsscrollView property. You can use the scroll view to learn and set how far the content is scrolled and zoomed, and you can install a gesture recognizer on it, to detect gestures not intended for the web view itself.

A web view is zoomable if its scalesToFit property is YES; in that case, it initially scales its content to fit, and the user can zoom the content (this includes use of the gesture, familiar from Mobile Safari, whereby double-tapping part of a web page zooms to that region of the page). Like a text view (Chapter 10), its dataDetectorTypes property lets you set certain types of data to be automatically converted to tappable links.

It is possible to design an entire app that is effectively nothing but a UIWebView — especially if you have control of the server with which the user is interacting. Indeed, before the advent of iOS, an iPhone app was a web application. There are still iPhone apps that work this way, but such an approach to app design is outside the scope of this book.

A web view’s most important task is to render HTML content; like any browser, a web view understands HTML, CSS, and JavaScript. In order to construct content for a web view, you must know HTML, CSS, and JavaScript. Discussion of those languages is beyond the scope of this book; each would require a book (at least) of its own. The thing to bear in mind is that you can use a web view to display content that isn’t fetched from the Internet or that isn’t obviously (to the user) a web page. WebKit is a powerful layout (and animation) engine; HTML and CSS (and JavaScript) are how you tell it what to do. In my TidBITS News app, a UIWebView is the obvious way to present each individual article, because an article arrives through the RSS feed as HTML; but in other apps, such as my Latin flashcard app or my Zotz! game, I present the Help documentation in a UIWebView just because it’s so convenient for laying out styled text with pictures.

Web View Content

To obtain content for a web view initially, you’re going to need one of three things:

There is often more than one way to load a given piece of content. For instance, one of Apple’s own examples suggests that you display a PDF file in your app’s bundle by loading it as data, along these lines:

NSString *thePath =
    [[NSBundle mainBundle] pathForResource:@"MyPDF" ofType:@"pdf"];
NSData *pdfData = [NSData dataWithContentsOfFile:thePath];
[self.wv loadData:pdfData MIMEType:@"application/pdf"
                  textEncodingName:@"utf-8" baseURL:nil];

But the same thing can be done with a file URL and loadRequest:, like this:

NSURL* url =
    [[NSBundle mainBundle] URLForResource:@"MyPDF" withExtension:@"pdf"];
NSURLRequest* req = [[NSURLRequest alloc] initWithURL:url];
[self.wv loadRequest:req];

Similarly, in one of my apps, where the Help screen is a web view (Figure 11-1), the content is an HTML file along with some referenced image files. I used to load it like this:

NSString* path =
    [[NSBundle mainBundle] pathForResource:@"help" ofType:@"html"];
NSURL* url = [NSURL fileURLWithPath:path];
NSError* err = nil;
NSString* s = [NSString stringWithContentsOfURL:url
                  encoding:NSUTF8StringEncoding error:&err];
// error-checking omitted
[self.wv loadHTMLString:s baseURL:url];
A Help screen that’s a web view
Figure 11-1. A Help screen that’s a web view

Observe that I obtain both the string contents of the HTML file and the URL reference to the same file, the latter to act as a base URL so that the relative references to the images will work properly.

At the time I wrote that code, the NSBundle methodURLForResource:withExtension: didn’t yet exist. Now it does, and I load the web view simply by calling loadRequest: with the file URL:

NSString* path =
    [[NSBundle mainBundle] pathForResource:@"help" ofType:@"html"];
NSURL* url = [NSURL fileURLWithPath:path];
NSURLRequest* req = [[NSURLRequest alloc] initWithURL:url];
[self.wv loadRequest: req];

You can use loadHTMLString:baseURL: to form your own web view content dynamically as an NSString. For example, in the TidBITS News app, the content of an article is displayed in a web view that is loaded using loadHTMLString:baseURL:. The body of the article comes from an RSS feed, but it is wrapped in programmatically supplied material. Thus, in Figure 11-2, the right-aligned author byline and publication date, along with the overall formatting of the text (including the font size), are imposed as the web view appears.

A web view with dynamically formed content
Figure 11-2. A web view with dynamically formed content

There are many possible strategies for doing this. In the case of the TidBITS News app, I start with a template loaded from disk:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <style type="text/css">
      p.inflow_image {
        text-align:center;
      }
      div.indented_image {
        text-align:center;
        margin-left:0;
      }
      img {
        max-width:<maximagewidth>;
        height:auto;
      }
    </style>
  <title>no title</title>
</head>
<body style="font-size:<fontsize>px; font-family:Georgia;
margin:1px <margin>px">
  <!-- author and date -->
  <div style="width:100%">
    <span style="float:right; margin-bottom: 15px; display:block;
    text-align:right; font-size:80%;">
      By <author><br><date>
    </span>
  </div>
  <!-- body, from feed -->
  <div style="clear:both; margin:30px 0px;">
    <content>
  </div>
</body>
</html>

The template defines the structure of an HTML document — the opening and closing tags, the head area (including some CSS styling), and a body consisting of <div>s laying out the parts of the page. But it also includes some pseudotags that are not HTML — <maximagewidth><fontsize>, and so on. When the web view is to be loaded, the template will be read from disk and real values will be substituted for those pseudotags:

NSString* template =
    [NSString stringWithContentsOfFile:
        [[NSBundle mainBundle] pathForResource:@"template" ofType:@"txt"]
            encoding: NSUTF8StringEncoding error:nil];
NSString* s = template;
s = [s stringByReplacingOccurrencesOfString:@"<maximagewidth>"
                                 withString:maxImageWidth];
s = [s stringByReplacingOccurrencesOfString:@"<fontsize>"
                                 withString:fontsize.stringValue];
s = [s stringByReplacingOccurrencesOfString:@"<margin>"
                                 withString:margin];
s = [s stringByReplacingOccurrencesOfString:@"<author>"
                                 withString:anitem.authorOfItem];
s = [s stringByReplacingOccurrencesOfString:@"<date>"
                                 withString:date];
s = [s stringByReplacingOccurrencesOfString:@"<content>"
                                 withString:anitem.content];

Some of these arguments, such as anitem.authorOfItem andanitem.content, slot values more or less directly from the app’s model into the web view. Others are derived from the current circumstances. For example, the local variable margin has been set depending on whether the app is running on the iPhone or on the iPad; fontsize comes from the user defaults, because the user is allowed to determine how large the text should be. The result is an HTML string ready for loadHTMLString:baseURL:.

Web view content is loaded asynchronously (gradually, in a thread of its own), and it might not be loaded at all (because the user might not be connected to the Internet, the server might not respond properly, and so on). If you’re loading a resource directly from disk, loading is quick and nothing is going to go wrong; nevertheless, rendering the content can take time, and even a resource loaded from disk, or content formed directly as an HTML string, might refer to material out on the Internet that takes time to fetch.

Your app’s interface is not blocked or frozen while the content is loading. On the contrary, it remains accessible and operative; that’s what “asynchronous” means. The web view, in fetching a web page and its linked components, is doing something quite complex, involving both threading and network interaction — I’ll have a lot more to say about this in Chapter 24 andChapter 25 — but it shields you from this complexity. Your own interaction with the web view stays on the main thread and is straightforward. You ask the web view to load some content; then you sit back and let it worry about the details.

Indeed, there’s very little you can do once you’ve asked a web view to load content. Your main concerns will probably be to know when loading really starts, when it has finished, and whether it succeeded. To help you with this, a UIWebView’s delegate (adopting the UIWebViewDelegate protocol) gets three messages:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值