UIWebView

description

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

properties

// UIWebView的代理(不包含UIScrollViewDelegate,如果需要可以通过scrollView属性来设置)
@property (nullable, nonatomic, assign) id  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


    UIWebView_第1张图片
    safari调试.png
  • 不能继承UIWebView

参考文献

UIWebView&WKWebView如何实现OC与JS互调
UIWebView与WKWebView基本使用

你可能感兴趣的:(UIWebView)