准备面试,很多公司要求要会这个,之前做过的项目确实没有这方面的需求,所以来学习学习。
因为当前都是WKWebView,UIWebView不做讨论了。
交互无非就是互相调用彼此方法。
1.oc调用js的方法
- 记得传给js的参数要加单引号。
- 回调中的data是js方法的返回值。
- 执行js方法时,需要确定web view已经加载完毕。(必要时可以在didFinishNavigation协议中延时调用)
// iOS
[self.webView evaluateJavaScript:@"jsFunc('123')" completionHandler:^(id data, NSError *error) {
NSLog(@"%@--%@", data, error);
}];
// js中,如果方法要暴露给oc使用,需要将方法挂载到window下。
// 如果使用的是vue,则需要在onMounted方法中,将方法挂载到window下
2. js调用oc的方法
iOS提供了内容交互控制器(userContentController)可以用来与js交互
它是属于配置项中的属性:webView.configuration.userContentController.
- 将oc的方法注册到web中,使用 -addScriptMessageHandler:<WKScriptMessageHandler> name:@""
- 此时即可在js中,使用window.webkit.messageHandlers.<ocFuncName>.postMessage(null) 调用oc方法
这个参数是必传的,否则不会进入代理方法。
- 遵守WKScriptMessageHandler协议,协议中 -didReceiveScriptMessage方法
可以获取到 js调用的是oc的哪个方法,还有具体的参数,再做出具体的处理
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
NSLog(@"%@", message.body);
NSLog(@"%@", message.name);
if ([message.name isEqualToString:@""]) {
//
}
}
3. web view的加载进度条
web view有一个属性:estimatedProgress
/*! @abstract An estimate of what fraction of the current navigation has been completed.
@discussion This value ranges from 0.0 to 1.0 based on the total number of
bytes expected to be received, including the main document and all of its
potential subresources. After a navigation completes, the value remains at 1.0
until a new navigation starts, at which point it is reset to 0.0.
@link WKWebView @/link is key-value observing (KVO) compliant for this
property.
*/
@property (nonatomic, readonly) double estimatedProgress;
所以直接kvo监听就可以了
[self.webView addObserver:self forKeyPath:@"estimatedProgress" options:(NSKeyValueObservingOptionNew) context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"estimatedProgress"]) {
double prog = [[change objectForKey:NSKeyValueChangeNewKey] doubleValue];
//将获取到的值赋值给进度条控件就好
[self.progressView setProgress:prog animated:true];
}
}