前言

NS_CLASS_AVAILABLE_IOS(2_0) __TVOS_PROHIBITED @interface UIWebView : UIView <NSCoding, 
        UIScrollViewDelegate> 
    @available(iOS 2.0, *) public class UIWebView : UIView, NSCoding, UIScrollViewDelegate
    NS_CLASS_AVAILABLE_IOS(2_0) __TVOS_PROHIBITED @interface UIWebView : UIView <NSCoding, 
        UIScrollViewDelegate> 
    @available(iOS 2.0, *) public class UIWebView : UIView, NSCoding, UIScrollViewDelegate
  • UIWebView 控件是做网络应用开发时使用的最多的一个控件,它实现了内置的浏览器(类似于 Safari),并且 UIWebView 继承自 UIView,可以将其像其它控件一样应用到需要的位置。
  • 优点:简单,快速。
  • 缺点:内存消耗大,对于手机端的硬件支持不够好,例如:定位,捏合(传统互联网只有点击动作)。
  • 应用场景:
  1. 适合于内容版式变化比较大的应用。
    网易新闻,各种图文混排,甚至嵌入视频。
    菜谱,各种图片搭配,图文并茂。
    运动类的应用:羽毛球,后场高远球,来一段视频,图解说明,分解动作...。
  2. 有些公司,有网站,没有 iOS 应用,着急上架,可以先用 webView 快速包装一个。
    百度的一系列应用,去年年初才慢慢的转成 iOS 应用。
  3. iPhone 手机的浏览器 Safari 就是用 UIWebView 控件开发的。
    微信内嵌的浏览器就是 UIWebView 控件
  • iOS 9+ 中若要加载 http: 网络,需要在 Info.plist 中添加 App Transport Security Settings -> key: Allow Arbitrary Loads,value: YES。

1、UIWebView 的创建

  • Objective-C
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 20, self.view.bounds.size.width, self.view.bounds.size.height-20)];

    // 将 webView 添加到屏幕
    [self.view addSubview:webView];

    // 加载网络地址
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];

    // 适配屏幕
    webView.scalesPageToFit = YES;
    UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 20, self.view.bounds.size.width, self.view.bounds.size.height-20)];

    // 将 webView 添加到屏幕
    [self.view addSubview:webView];

    // 加载网络地址
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];

    // 适配屏幕
    webView.scalesPageToFit = YES;
  • Swift
let webView:UIWebView = UIWebView(frame: CGRectMake(0, 20, self.view.bounds.size.width, self.view.bounds.size.height-20))

    // 将 webView 添加到屏幕
    self.view.addSubview(webView)

    // 加载网络地址
    webView.loadRequest(NSURLRequest(URL: NSURL(string: "http://www.baidu.com")!))

    // 适配屏幕
    webView.scalesPageToFit = true
    let webView:UIWebView = UIWebView(frame: CGRectMake(0, 20, self.view.bounds.size.width, self.view.bounds.size.height-20))

    // 将 webView 添加到屏幕
    self.view.addSubview(webView)

    // 加载网络地址
    webView.loadRequest(NSURLRequest(URL: NSURL(string: "http://www.baidu.com")!))

    // 适配屏幕
    webView.scalesPageToFit = true

2、UIWebView 的设置

  • Objective-C
// 加载指定 URL 所设定的内容
    /*
        异步加载,可以从服务器和本地读取
    */

        // 加载网络数据
        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];

        // 加载本地文件
        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Baidu" 
                                                                                                                 ofType:@"pdf"]]]];

    // 加载 HTML 字符串数据
    /*
        指定 baseURL 可加载图片
    */

        // 加载网络 HTML 字符串数据
        NSString *htmlString1 = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"https://m.baidu.com/"] 
                                                         encoding:NSUTF8StringEncoding 
                                                            error:NULL];
        [webView loadHTMLString:htmlString1 baseURL:[NSURL URLWithString:@"https://m.baidu.com/"]];

        // 加载本地 HTML 字符串数据
        NSString *htmlString2 = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Baidu" ofType:@"html"] 
                                                          encoding:NSUTF8StringEncoding 
                                                             error:NULL];
        [webView loadHTMLString:htmlString2 baseURL:nil];

    // 加载 Data 数据
    /*
        比 loadHTMLString 更底层
    */
    NSData *data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Baidu" ofType:@"html"]]];
    [webView loadData:data MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:[NSURL URLWithString:@"https://m.baidu.com/"]];

    // 适配屏幕
    /*
        YES 页面可以通过放大和缩小去适应,用户也可以通过手势来放大和缩小
    */
    webView.scalesPageToFit = YES;

    // 设置自动分页模式
    /*
        UIWebPaginationModeUnpaginated,   // 默认不分页
        UIWebPaginationModeLeftToRight,
        UIWebPaginationModeTopToBottom,
        UIWebPaginationModeBottomToTop,
        UIWebPaginationModeRightToLeft
     */
    webView.paginationMode = UIWebPaginationModeLeftToRight;

    // 设置超链接类型
    /*
        UIDataDetectorTypePhoneNumber     = 1 << 0,          // Phone number detection
        UIDataDetectorTypeLink            = 1 << 1,          // URL detection
        UIDataDetectorTypeAddress         = 1 << 2,          // Street address detection
        UIDataDetectorTypeCalendarEvent   = 1 << 3,          // Event detection

        UIDataDetectorTypeNone            = 0,               // No detection at all
        UIDataDetectorTypeAll             = NSUIntegerMax    // All types
    */
    webView.dataDetectorTypes = UIDataDetectorTypeAll;

    // 设置是否用内嵌 HTML5 播放视频
    /*
        内嵌播放 HTML 中的 video 元素必须包含 webkit-playsinline 属性
        YES 内嵌播放,NO 本地全屏控制,iPhone Safari defaults to NO. iPad Safari defaults to YES
    */
    webView.allowsInlineMediaPlayback = NO;

    // 设置是否需要用户触发来启动媒体播放
    /*
        iPhone and iPad Safari both default to YES
    */
    webView.mediaPlaybackRequiresUserAction = NO;

    // 设置本页面是否可以 AirPlay 播放
    /*
        iPhone and iPad Safari both default to YES
    */
    webView.mediaPlaybackAllowsAirPlay = YES;

    // 设置是否把网页内容全部加载到内存中再去渲染
    /*
        iPhone and iPad Safari both default to NO
    */
    webView.suppressesIncrementalRendering = NO;

    // 设置是否需要用户触发显示键盘
    /*
        default is YES
    */
    webView.keyboardDisplayRequiresUserAction = NO;

    // 刷新
    /*
        重新加载页面
    */
    [webView reload];

    // 停止加载
    /*
        加载过程中,强行停止加载
    */
    [webView stopLoading]; 

    // 返回至上一个链接
    /*
        在产生多个链接浏览时,可以返回至浏览历史的上一个链接
    */
    [webView goBack];

    // 前进至下一个链接
    /*
        在产生多个链接浏览时,可以前进至浏览历史的下一个链接
    */
    [webView goForward];

    // 设置代理,需遵守协议 <UIWebViewDelegate>
    webView.delegate = self;
    // 加载指定 URL 所设定的内容
    /*
        异步加载,可以从服务器和本地读取
    */

        // 加载网络数据
        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];

        // 加载本地文件
        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Baidu" 
                                                                                                                 ofType:@"pdf"]]]];

    // 加载 HTML 字符串数据
    /*
        指定 baseURL 可加载图片
    */

        // 加载网络 HTML 字符串数据
        NSString *htmlString1 = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"https://m.baidu.com/"] 
                                                         encoding:NSUTF8StringEncoding 
                                                            error:NULL];
        [webView loadHTMLString:htmlString1 baseURL:[NSURL URLWithString:@"https://m.baidu.com/"]];

        // 加载本地 HTML 字符串数据
        NSString *htmlString2 = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Baidu" ofType:@"html"] 
                                                          encoding:NSUTF8StringEncoding 
                                                             error:NULL];
        [webView loadHTMLString:htmlString2 baseURL:nil];

    // 加载 Data 数据
    /*
        比 loadHTMLString 更底层
    */
    NSData *data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Baidu" ofType:@"html"]]];
    [webView loadData:data MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:[NSURL URLWithString:@"https://m.baidu.com/"]];

    // 适配屏幕
    /*
        YES 页面可以通过放大和缩小去适应,用户也可以通过手势来放大和缩小
    */
    webView.scalesPageToFit = YES;

    // 设置自动分页模式
    /*
        UIWebPaginationModeUnpaginated,   // 默认不分页
        UIWebPaginationModeLeftToRight,
        UIWebPaginationModeTopToBottom,
        UIWebPaginationModeBottomToTop,
        UIWebPaginationModeRightToLeft
     */
    webView.paginationMode = UIWebPaginationModeLeftToRight;

    // 设置超链接类型
    /*
        UIDataDetectorTypePhoneNumber     = 1 << 0,          // Phone number detection
        UIDataDetectorTypeLink            = 1 << 1,          // URL detection
        UIDataDetectorTypeAddress         = 1 << 2,          // Street address detection
        UIDataDetectorTypeCalendarEvent   = 1 << 3,          // Event detection

        UIDataDetectorTypeNone            = 0,               // No detection at all
        UIDataDetectorTypeAll             = NSUIntegerMax    // All types
    */
    webView.dataDetectorTypes = UIDataDetectorTypeAll;

    // 设置是否用内嵌 HTML5 播放视频
    /*
        内嵌播放 HTML 中的 video 元素必须包含 webkit-playsinline 属性
        YES 内嵌播放,NO 本地全屏控制,iPhone Safari defaults to NO. iPad Safari defaults to YES
    */
    webView.allowsInlineMediaPlayback = NO;

    // 设置是否需要用户触发来启动媒体播放
    /*
        iPhone and iPad Safari both default to YES
    */
    webView.mediaPlaybackRequiresUserAction = NO;

    // 设置本页面是否可以 AirPlay 播放
    /*
        iPhone and iPad Safari both default to YES
    */
    webView.mediaPlaybackAllowsAirPlay = YES;

    // 设置是否把网页内容全部加载到内存中再去渲染
    /*
        iPhone and iPad Safari both default to NO
    */
    webView.suppressesIncrementalRendering = NO;

    // 设置是否需要用户触发显示键盘
    /*
        default is YES
    */
    webView.keyboardDisplayRequiresUserAction = NO;

    // 刷新
    /*
        重新加载页面
    */
    [webView reload];

    // 停止加载
    /*
        加载过程中,强行停止加载
    */
    [webView stopLoading]; 

    // 返回至上一个链接
    /*
        在产生多个链接浏览时,可以返回至浏览历史的上一个链接
    */
    [webView goBack];

    // 前进至下一个链接
    /*
        在产生多个链接浏览时,可以前进至浏览历史的下一个链接
    */
    [webView goForward];

    // 设置代理,需遵守协议 <UIWebViewDelegate>
    webView.delegate = self;
  • Swift
// 加载指定 URL 所设定的内容
    /*
        异步加载,可以从服务器和本地读取
    */

        // 加载网络数据
        webView.loadRequest(NSURLRequest(URL: NSURL(string: "http://www.baidu.com")!))

        // 加载本地文件                                                   
        webView.loadRequest(NSURLRequest(URL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Baidu", ofType: "pdf")!)))

    // 加载 HTML 字符串数据
    /*
        指定 URL 可加载图片
    */

        // 加载网络 HTML 字符串数据
        let htmlString1:String = try! String(contentsOfURL: NSURL(string: "https://m.baidu.com/")!, encoding: NSUTF8StringEncoding)
        webView.loadHTMLString(htmlString1, baseURL: NSURL(string: "https://m.baidu.com/")!)

        // 加载本地 HTML 字符串数据
        let htmlString2:String = try! String(contentsOfFile: NSBundle.mainBundle().pathForResource("Baidu", ofType: "html")!, 
                                                   encoding: NSUTF8StringEncoding)
        webView.loadHTMLString(htmlString2, baseURL: nil)

    // 加载 Data 数据
    /*
        比 loadHTMLString 更底层
    */
    let data = NSData(contentsOfURL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Baidu", ofType: "html")!))
    webView.loadData(data!, MIMEType: "text/html", textEncodingName: "utf-8", baseURL: NSURL(string: "https://m.baidu.com/")!)

    // 适配屏幕
    /*
        true 页面可以通过放大和缩小去适应,用户也可以通过手势来放大和缩小
    */
    webView.scalesPageToFit = true

    // 设置自动分页模式
    /*
        case Unpaginated    // 默认不分页
        case LeftToRight
        case TopToBottom
        case BottomToTop
        case RightToLeft
    */
    webView.paginationMode = .Unpaginated

    // 设置超链接类型
    /*
        PhoneNumber     // Phone number detection
        Link            // URL detection
        Address         // Street address detection
        CalendarEvent   // Event detection

        None            // No detection at all
        All             // All types
    */
    webView.dataDetectorTypes = .All

    // 设置是否用内嵌 HTML5 播放视频
    /*
        内嵌播放 HTML 中的 video 元素必须包含 webkit-playsinline 属性
        YES 内嵌播放,NO 本地全屏控制,iPhone Safari defaults to NO. iPad Safari defaults to YES
    */
    webView.allowsInlineMediaPlayback = false

    // 设置是否需要用户触发来启动媒体播放
    /*
        iPhone and iPad Safari both default to YES
    */
    webView.mediaPlaybackRequiresUserAction = false

    // 设置本页面是否可以 AirPlay 播放
    /*
        iPhone and iPad Safari both default to YES
    */
    webView.mediaPlaybackAllowsAirPlay = true

    // 设置是否把网页内容全部加载到内存中再去渲染
    /*
        iPhone and iPad Safari both default to NO
    */
    webView.suppressesIncrementalRendering = false

    // 设置是否需要用户触发显示键盘
    /*
        default is YES
    */
    webView.keyboardDisplayRequiresUserAction = false

    // 刷新
    /*
        重新加载页面
    */
    webView.reload()

    // 停止加载
    /*
        加载过程中,强行停止加载
    */
    webView.stopLoading()

    // 返回至上一个链接
    /*
        在产生多个链接浏览时,可以返回至浏览历史的上一个链接
    */
    webView.goBack()

    // 前进至下一个链接
    /*
        在产生多个链接浏览时,可以前进至浏览历史的下一个链接
    */
    webView.goForward()

    // 设置代理,需遵守协议 UIWebViewDelegate
    webView.delegate = self
    // 加载指定 URL 所设定的内容
    /*
        异步加载,可以从服务器和本地读取
    */

        // 加载网络数据
        webView.loadRequest(NSURLRequest(URL: NSURL(string: "http://www.baidu.com")!))

        // 加载本地文件                                                   
        webView.loadRequest(NSURLRequest(URL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Baidu", ofType: "pdf")!)))

    // 加载 HTML 字符串数据
    /*
        指定 URL 可加载图片
    */

        // 加载网络 HTML 字符串数据
        let htmlString1:String = try! String(contentsOfURL: NSURL(string: "https://m.baidu.com/")!, encoding: NSUTF8StringEncoding)
        webView.loadHTMLString(htmlString1, baseURL: NSURL(string: "https://m.baidu.com/")!)

        // 加载本地 HTML 字符串数据
        let htmlString2:String = try! String(contentsOfFile: NSBundle.mainBundle().pathForResource("Baidu", ofType: "html")!, 
                                                   encoding: NSUTF8StringEncoding)
        webView.loadHTMLString(htmlString2, baseURL: nil)

    // 加载 Data 数据
    /*
        比 loadHTMLString 更底层
    */
    let data = NSData(contentsOfURL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Baidu", ofType: "html")!))
    webView.loadData(data!, MIMEType: "text/html", textEncodingName: "utf-8", baseURL: NSURL(string: "https://m.baidu.com/")!)

    // 适配屏幕
    /*
        true 页面可以通过放大和缩小去适应,用户也可以通过手势来放大和缩小
    */
    webView.scalesPageToFit = true

    // 设置自动分页模式
    /*
        case Unpaginated    // 默认不分页
        case LeftToRight
        case TopToBottom
        case BottomToTop
        case RightToLeft
    */
    webView.paginationMode = .Unpaginated

    // 设置超链接类型
    /*
        PhoneNumber     // Phone number detection
        Link            // URL detection
        Address         // Street address detection
        CalendarEvent   // Event detection

        None            // No detection at all
        All             // All types
    */
    webView.dataDetectorTypes = .All

    // 设置是否用内嵌 HTML5 播放视频
    /*
        内嵌播放 HTML 中的 video 元素必须包含 webkit-playsinline 属性
        YES 内嵌播放,NO 本地全屏控制,iPhone Safari defaults to NO. iPad Safari defaults to YES
    */
    webView.allowsInlineMediaPlayback = false

    // 设置是否需要用户触发来启动媒体播放
    /*
        iPhone and iPad Safari both default to YES
    */
    webView.mediaPlaybackRequiresUserAction = false

    // 设置本页面是否可以 AirPlay 播放
    /*
        iPhone and iPad Safari both default to YES
    */
    webView.mediaPlaybackAllowsAirPlay = true

    // 设置是否把网页内容全部加载到内存中再去渲染
    /*
        iPhone and iPad Safari both default to NO
    */
    webView.suppressesIncrementalRendering = false

    // 设置是否需要用户触发显示键盘
    /*
        default is YES
    */
    webView.keyboardDisplayRequiresUserAction = false

    // 刷新
    /*
        重新加载页面
    */
    webView.reload()

    // 停止加载
    /*
        加载过程中,强行停止加载
    */
    webView.stopLoading()

    // 返回至上一个链接
    /*
        在产生多个链接浏览时,可以返回至浏览历史的上一个链接
    */
    webView.goBack()

    // 前进至下一个链接
    /*
        在产生多个链接浏览时,可以前进至浏览历史的下一个链接
    */
    webView.goForward()

    // 设置代理,需遵守协议 UIWebViewDelegate
    webView.delegate = self

3、UIWebView 的协议方法

  • 需遵守协议 UIWebViewDelegate,并设置代理
  • Objective-C
// 将要开始加载网页
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

        return YES;
    }

    // 开始加载网页
    - (void)webViewDidStartLoad:(UIWebView *)webView {

    }

    // 加载网页完成
    - (void)webViewDidFinishLoad:(UIWebView *)webView {

    }

    // 加载网页失败
    - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {

    }
    // 将要开始加载网页
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

        return YES;
    }

    // 开始加载网页
    - (void)webViewDidStartLoad:(UIWebView *)webView {

    }

    // 加载网页完成
    - (void)webViewDidFinishLoad:(UIWebView *)webView {

    }

    // 加载网页失败
    - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {

    }
  • Swift
// 将要开始加载网页
    func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {

        return true
    }

    // 开始加载网页
    func webViewDidStartLoad(webView: UIWebView) {

    }

    // 加载网页完成
    func webViewDidFinishLoad(webView: UIWebView) {

    }

    // 加载网页失败
    func webView(webView: UIWebView, didFailLoadWithError error: NSError?) {

    }
    // 将要开始加载网页
    func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {

        return true
    }

    // 开始加载网页
    func webViewDidStartLoad(webView: UIWebView) {

    }

    // 加载网页完成
    func webViewDidFinishLoad(webView: UIWebView) {

    }

    // 加载网页失败
    func webView(webView: UIWebView, didFailLoadWithError error: NSError?) {

    }