UIWebView

作者: BrightFuture | 来源:发表于2016-11-24 11:23 被阅读0次

    description

    通过UIWebView这个类,可以将web内容嵌入到app中。使用步骤分两步,第一步创建一个UIWebView对象,将它添加到window上,第二步发送一个请求去加载web内容。通过这个类可以在访问网页历史记录中的前一页或后一页,甚至还可以通过编程的方式设置一些网页内容的属性

    properties

    // UIWebView的代理(不包含UIScrollViewDelegate,如果需要可以通过scrollView属性来设置)
    @property (nullable, nonatomic, assign) id <UIWebViewDelegate> delegate;
    
    // UIWebView内部的scrollView,可以通过设置scrollView的delegate来监听UIWebView的滚动
    @property (nonatomic, readonly, strong) UIScrollView *scrollView;
    
    // 加载webView的请求,在加载完成后可以拿到
    @property (nullable, nonatomic, readonly, strong) NSURLRequest *request;
    
    // 是否可以后退,为YES时才能调用goBack方法
    @property (nonatomic, readonly, getter=canGoBack) BOOL canGoBack;
    
    // 是否可以前进,为YES时才能调用goForward方法
    @property (nonatomic, readonly, getter=canGoForward) BOOL canGoForward;
    
    // 是否正在加载,加载完成或调用stopLoading方法后为NO
    @property (nonatomic, readonly, getter=isLoading) BOOL loading;
    
    // 设置web内容是否适应webView的尺寸
    // YES相当于UIViewContentModeScaleToFit,而且此时用户可以通过手势放大缩小web内容
    // 为NO时尺寸为web内容的真实尺寸,且不能通过手势放大缩小,默认为NO
    @property (nonatomic) BOOL scalesPageToFit;
    
    // 数据检测器类型
    // 用于检测web中的特殊内容(电话号码、地址、超链接等),点击被检测的web内容时会出现特定功能选择框
    @property (nonatomic) UIDataDetectorTypes dataDetectorTypes
    
    // 是否使用HTML中内联播放器播放视频
    // 事实上还需要在HTML中的video标签添加webkit-playsinline属性,否则还是会使用系统的全屏播放器
    // iPhone Safari defaults to NO. iPad Safari defaults to YES
    @property (nonatomic) BOOL allowsInlineMediaPlayback;
    
    // 设置视频是否自动播放,NO自动播放,YES需要点击才可以播放
    // 还需要在HTML的video标签中添加autoplay属性,否则无法自动播放
    // iPhone and iPad Safari both default to YES
    @property (nonatomic) BOOL mediaPlaybackRequiresUserAction;
    
    // 设置音频播放是否支持air play功能,iPhone and iPad Safari both default to YES
    @property (nonatomic) BOOL mediaPlaybackAllowsAirPlay;
    
    // 设置是否将数据加载入内存后渲染界面,iPhone and iPad Safari both default to NO
    @property (nonatomic) BOOL suppressesIncrementalRendering;
    
    // 设置是否能够打开键盘在webView上交互,default is YES
    @property (nonatomic) BOOL keyboardDisplayRequiresUserAction;
    
    // 设置当网页内容超过UIWebView的尺寸时的布局方式,一般会设置UIWebView的scrollView.pagingEnabled = YES一起使用
    @property (nonatomic) UIWebPaginationMode paginationMode;
    typedef NS_ENUM(NSInteger, UIWebPaginationMode) { 
    UIWebPaginationModeUnpaginated, //不使用翻页效果 
    UIWebPaginationModeLeftToRight, //将网页超出部分分页,从左向右进行翻页 
    UIWebPaginationModeTopToBottom, //将网页超出部分分页,从上向下进行翻页 
    UIWebPaginationModeBottomToTop, //将网页超出部分分页,从下向上进行翻页 
    UIWebPaginationModeRightToLeft //将网页超出部分分页,从右向左进行翻页 
    };
    
    // 设置每一页的尺寸,如果是上下分页就是每页的高度,如果是左右分页就是每页的宽度
    @property (nonatomic) CGFloat pageLength;
    
    // 每页之间的间距
    @property (nonatomic) CGFloat gapBetweenPages;
    
    // 总页数
    @property (nonatomic, readonly) NSUInteger pageCount;
    
    // 这个属性决定CSS的属性分页是可用还是忽略。默认是UIWebPaginationBreakingModePage
    @property (nonatomic) UIWebPaginationBreakingMode paginationBreakingMode; 
    
    // 是否支持画中画
    @property (nonatomic) BOOL allowsPictureInPictureMediaPlayback NS_AVAILABLE_IOS(9_0); 
    
    // 设置是否支持超链接的3DTouch操作(peek和pop)
    @property (nonatomic) BOOL allowsLinkPreview NS_AVAILABLE_IOS(9_0);
    

    methods

    加载UIWebView内容

    • 方法一
      // 根据NSURLRequest创建一个异步请求加载UIWebView,可以通过stopLoading停止加载或通过loading属性查看是否正在加载
      // 加载本地的HTML文件时一般用loadHTMLString:baseURL:,但是可以用来加载本地的其他文件如PDF等
      - (void)loadRequest:(NSURLRequest *)request;
      
      // 加载本地文件(非HTML)
      NSString *path = [[NSBundle mainBundle] pathForResource:documentName ofType:nil];
      NSURL *url = [NSURL fileURLWithPath:path];
      NSURLRequest *request = [NSURLRequest requestWithURL:url];
      [webView loadRequest:request];
    
    • 方法二
      // 加载本地HTML文件,string为HTML的文本内容,baseURL指的是CSS、JS资源路径,如果CSS、JS是本地的,就用[[NSBundle mainbundle] resourceURL]即资源包路径,如果是网络资源写nil即可
      - (void)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
      
      // 加载本地HTML文件
      NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"index.html" ofType:nil]];
      NSString *htmlStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
      [webView loadHTMLString:htmlStr baseURL:[[NSBundle mainBundle] resourceURL]];
    
    • 方法三
      // 根据NSData加载UIWebView
      - (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)textEncodingName baseURL:(NSURL *)baseURL;
      
      NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"index.html" ofType:nil]];
      [webView loadData:data MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:[[NSBundle mainBundle] resourceURL]];
    

    代理方法UIWebViewDelegate

      // webView加载任何一个frame前都会调用该方法,如果返回NO,就不处理这个请求(后续的代理不会执行)
      // UIWebViewNavigationType定义了用户在页面上行为
      typedef NS_ENUM(NSInteger, UIWebViewNavigationType) {
        UIWebViewNavigationTypeLinkClicked,     //用户触击了一个链接
        UIWebViewNavigationTypeFormSubmitted,   //用户提交了一个表单
        UIWebViewNavigationTypeBackForward,     //用户触击前进或返回按钮
        UIWebViewNavigationTypeReload,          //用户触击重新加载的按钮
        UIWebViewNavigationTypeFormResubmitted, //用户重复提交表单
        UIWebViewNavigationTypeOther            //发生其它行为
      } __TVOS_PROHIBITED;
      - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
      
      // webView开始加载之后调用
      - (void)webViewDidStartLoad:(UIWebView *)webView;
      
      // webView结束加载之后调用
      - (void)webViewDidFinishLoad:(UIWebView *)webView;
      
      // webView加载失败后调用
       - (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error;
    

    其他方法

      // 刷新网页,重新请求一次
      - (void)reload;
    
      // 停止网页加载内容
      - (void)stopLoading;
    
      // 后退,执行前先判断下canGoBack
      - (void)goBack;
    
      // 前进,执行前先判断下canGoForward
      - (void)goForward;
    

    很重要的方法:stringByEvaluatingJavaScriptFromString:

    我们可以利用stringByEvaluatingJavaScriptFromString:直接执行某个js方法

      function hello() {
        alert("Hello World!");
      }
      [self.webView stringByEvaluatingJavaScriptFromString:@"hello()"];
    

    也可以通过这个方法定义function

      NSString *helloFunction = @"function hello() { \
                                        alert('Hello World'); \
                                    } \
                                    hello();";
      [self.webView stringByEvaluatingJavaScriptFromString:helloFunction];
    
    • 如果上面的方法是在webViewDidFinishLoad:方法中执行的,会出现一些闪屏现象,原因是渲染过后,内部处理JS代码后,页面会再渲染一次
    • stringByEvaluatingJavaScriptFromString:必须在主线程中执行,否则会报错,因为它涉及到UI渲染

    important

    • 不要在UIScrollView中添加UIWebView或者UITableView,这样可能会造成两个对象触摸事件混乱或被错误的处理
    • 使用safari的调试工具可以调试UIWebView中加载的html、CSS、javaScript


      safari调试.png
    • 不能继承UIWebView

    参考文献

    <a href="http://www.jianshu.com/p/84a6b1ac974a">UIWebView&WKWebView如何实现OC与JS互调</a>
    <a href="http://www.jianshu.com/p/b3e7fa514ab7?mType=Group"> UIWebView与WKWebView基本使用</a>

    相关文章

      网友评论

          本文标题:UIWebView

          本文链接:https://www.haomeiwen.com/subject/qbjbpttx.html