最近項(xiàng)目里用到了web界面與js交互,項(xiàng)目使用的是UIWebView,但是會出現(xiàn)數(shù)據(jù)丟失的情況比較麻煩,使用WKWebView可以避免這種情況,下面就寫一些web的基本使用,可能有些使用不當(dāng)?shù)牡胤剑堉附獭?* UIWebView 創(chuàng)建一個類文件,可以定義交互時的函數(shù)名,然后定義一個代理,在web界面調(diào)用進(jìn)行相應(yīng)的操作。 “` //類的.h文件 # import
//類的.m文件 #import "KQJSModel.h"#import "KQPayTypeViewController.h"@implementation KQJSModel-(void)startPay:(int)amount Action:(NSString *)action Teamid:(NSString *)teamid{ NSLog(@"--------amount:%d---------action:%@------teamid:%@",amount,action,teamid); if (self.delegate && [self.delegate respondsToSelector:@selector(goToPayVC:action:teamid:)]) { [self.delegate goToPayVC:amount action:[NSString stringWithFormat:@"%@",action] teamid:[NSString stringWithFormat:@"%@",teamid]]; }}@end//web界面,在代理方法里注入方法名,-(void)webViewDidStartLoad:(UIWebView *)webView{ //首先創(chuàng)建JSContext 對象(此處通過當(dāng)前webView的鍵獲取到j(luò)scontext) JSContext *context=[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScrJavascriptFromString:@"document.title"];; NSLog(@"-----網(wǎng)頁標(biāo)題---%@",htmlTitle); self.title = [NSString stringWithFormat:@"%@",htmlTitle]; //首先創(chuàng)建JSContext 對象(此處通過當(dāng)前webView的鍵獲取到j(luò)scontext) JSContext *context=[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; //第二種情況,js是通過對象調(diào)用的,我們假設(shè)js里面有一個對象 testobject 在調(diào)用方法 //首先創(chuàng)建我們新建類的對象,將他賦值給js的對象 KQJSModel *testJO=[[KQJSModel alloc] init]; testJO.delegate = self; //類的協(xié)議代理 context[@"IOSApp"]=testJO;}//再調(diào)用KQJSModel類的代理方法,在代理方法里實(shí)現(xiàn)想要的進(jìn)行的操作。#PRagma mark -- KQJSModelDelegate-(void)goToPayVC:(int)amount action:(NSString *)action teamid:(NSString *)teamid{//進(jìn)行界面跳轉(zhuǎn),刷新,一定要在主線程里,不然會崩潰 dispatch_async(dispatch_get_main_queue(), ^{ KQPayTypeViewController *pay = [[KQPayTypeViewController alloc] init]; pay.money = [NSString stringWithFormat:@"%d",amount]; pay.action = [NSString stringWithFormat:@"%@",action]; pay.teamid = [NSString stringWithFormat:@"%@",teamid]; if (![action isEqualToString:@""] && action != nil) { pay.vip = @"vip"; } KQCommonNavController *nav = [[KQCommonNavController alloc]initWithRootViewController:pay]; [self presentViewController:nav animated:YES completion:nil]; });}以上就是UIWebView與js的交互,運(yùn)行就可以進(jìn)行相應(yīng)的操作了。
WKWebView 最近才看了WKWebView的使用,就感覺比UIWebView流暢寫,然后自帶的導(dǎo)航進(jìn)度條,這個感覺很方便,下面是與js的簡單的交互,有不正確的,請留言,謝謝~ #import "ViewController.h"#import <WebKit/WebKit.h>#define kScreenWidth [UIScreen mainScreen].bounds.size.width#define kScreenHeight [UIScreen mainScreen].bounds.size.height@interface ViewController ()<WKUIDelegate,WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler>@property (nonatomic, strong) WKWebView *wkWebView;@property (nonatomic, strong) WKWebViewConfiguration *wkConfig;/* *1.添加UIProgressView屬性 */@property (nonatomic, strong) UIProgressView *progressView;@end@implementation ViewController#pragma mark - 初始化wkWebView- (WKWebViewConfiguration *)wkConfig { if (!_wkConfig) { _wkConfig = [[WKWebViewConfiguration alloc] init]; _wkConfig.allowsInlineMediaPlayback = YES; _wkConfig.allowsPictureInPictureMediaPlayback = YES; _wkConfig.processPool = [[WKProcessPool alloc] init]; [_wkConfig.userContentController addScriptMessageHandler:self name:@"AppModel"]; //注入的js函數(shù)名, } return _wkConfig;}- (WKWebView *)wkWebView { if (!_wkWebView) { _wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight) configuration:self.wkConfig]; // 導(dǎo)航代理 _wkWebView.navigationDelegate = self; // 與webview UI交互代理 _wkWebView.UIDelegate = self; [self.view addSubview:_wkWebView]; } return _wkWebView;}/* *6.在dealloc中取消監(jiān)聽 */- (void)dealloc { [self.wkWebView removeObserver:self forKeyPath:@"estimatedProgress"];}- (void)viewDidLoad { [super viewDidLoad]; [self startLoad]; /* *2.初始化progressView */ self.progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 64, [[UIScreen mainScreen] bounds].size.width, 2)]; self.progressView.backgroundColor = [UIColor blueColor]; //設(shè)置進(jìn)度條的高度,下面這句代碼表示進(jìn)度條的寬度變?yōu)樵瓉淼?倍,高度變?yōu)樵瓉淼?.5倍. self.progressView.transform = CGAffineTransformMakeScale(1.0f, 1.5f); [self.view addSubview:self.progressView]; /* *3.添加KVO,WKWebView有一個屬性estimatedProgress,就是當(dāng)前網(wǎng)頁加載的進(jìn)度,所以監(jiān)聽這個屬性。 */ [self.wkWebView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil]; UIButton *bavkBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 16, 20)]; [bavkBtn setImage:[UIImage imageNamed:@"navback"] forState:UIControlStateNormal]; [bavkBtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside]; UIBarButtonItem *left = [[UIBarButtonItem alloc] initWithCustomView:bavkBtn]; self.navigationItem.leftBarButtonItem = left;}- (void)back{ if ([self.wkWebView canGoBack]) { [self.wkWebView goBack]; }}#pragma mark - start load web- (void)startLoad { NSString *urlString = @"https://testh5.keqiong.net/app/my-kqcoin.html?type=Driver"; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]]; request.timeoutInterval = 15.0f; [self.wkWebView loadRequest:request];}#pragma mark - 監(jiān)聽/* *4.在監(jiān)聽方法中獲取網(wǎng)頁加載的進(jìn)度,并將進(jìn)度賦給progressView.progress */- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { if ([keyPath isEqualToString:@"estimatedProgress"]) { self.progressView.progress = self.wkWebView.estimatedProgress; if (self.progressView.progress == 1) { /* *添加一個簡單的動畫,將progressView的Height變?yōu)?.4倍 *動畫時長0.25s,延時0.3s后開始動畫 *動畫結(jié)束后將progressView隱藏 */ __weak typeof (self)weakSelf = self; [UIView animateWithDuration:0.25f delay:0.3f options:UIViewAnimationOptionCurveEaSEOut animations:^{ weakSelf.progressView.transform = CGAffineTransformMakeScale(1.0f, 1.4f); } completion:^(BOOL finished) { weakSelf.progressView.hidden = YES; }]; } }else{ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; }}#pragma mark - WKWKNavigationDelegate Methods/* *5.在WKWebViewd的代理中展示進(jìn)度條,加載完成后隱藏進(jìn)度條 *///開始加載- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { NSLog(@"開始加載網(wǎng)頁"); //開始加載網(wǎng)頁時展示出progressView self.progressView.hidden = NO; //開始加載網(wǎng)頁的時候?qū)rogressView的Height恢復(fù)為1.5倍 self.progressView.transform = CGAffineTransformMakeScale(1.0f, 1.5f); //防止progressView被網(wǎng)頁擋住 [self.view bringSubviewToFront:self.progressView];}//加載完成- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { NSLog(@"加載完成");}//加載失敗- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error { NSLog(@"加載失敗"); //加載失敗同樣需要隱藏progressView self.progressView.hidden = YES;}//頁面跳轉(zhuǎn)- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { //允許頁面跳轉(zhuǎn) NSLog(@"%@",navigationAction.request.URL); decisionHandler(WKNavigationActionPolicyAllow);}#pragma mark - WKUIDelegate- (void)webViewDidClose:(WKWebView *)webView { NSLog(@"%s", __FUNCTION__);}// 在JS端調(diào)用alert函數(shù)時,會觸發(fā)此代理方法。// JS端調(diào)用alert時所傳的數(shù)據(jù)可以通過message拿到// 在原生得到結(jié)果后,需要回調(diào)JS,是通過completionHandler回調(diào)- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler { NSLog(@"%s", __FUNCTION__); UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"alert" message:@"JS調(diào)用alert" preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler(); }]]; [self presentViewController:alert animated:YES completion:NULL]; NSLog(@"%@", message);}// JS端調(diào)用confirm函數(shù)時,會觸發(fā)此方法// 通過message可以拿到JS端所傳的數(shù)據(jù)// 在iOS端顯示原生alert得到Y(jié)ES/NO后// 通過completionHandler回調(diào)給JS端- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler { NSLog(@"%s", __FUNCTION__); UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"confirm" message:@"JS調(diào)用confirm" preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler(YES); }]]; [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { completionHandler(NO); }]]; [self presentViewController:alert animated:YES completion:NULL]; NSLog(@"%@", message);}// JS端調(diào)用prompt函數(shù)時,會觸發(fā)此方法// 要求輸入一段文本// 在原生輸入得到文本內(nèi)容后,通過completionHandler回調(diào)給JS- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler { NSLog(@"%s", __FUNCTION__); NSLog(@"%@", prompt); UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"textinput" message:@"JS調(diào)用輸入框" preferredStyle:UIAlertControllerStyleAlert]; [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { textField.textColor = [UIColor redColor]; }]; [alert addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler([[alert.textFields lastObject] text]); }]]; [self presentViewController:alert animated:YES completion:NULL];}- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{}新聞熱點(diǎn)
疑難解答