WKWebView 其實是 UIWebView 的底層(應該可以這麼說)
為什麼要用WKWebView呢~其實是因為要呼叫JavaScript
讓網頁可以跟手機互相呼叫
但盡量使用純html的Code 因為有遇到ASP.NET 因為很多控制項是他們自己封裝的
手機版的WebView 會解析不出來會造成錯誤,但OSX版本的Safari卻又可以,但這又是另外一件事情了(ASP.NET 的問題是可以解決的
-本文開始-
首先
Framework 要加入 WebKit.framework
再來要
#import <WebKit/WebKit.h>
加入以下Delegate
@interface xxxViewController ()<WKScriptMessageHandler, WKNavigationDelegate,WKUIDelegate>
增加property
@property (nonatomic,strong) WKWebView* webView;
@property (nonatomic, strong) WKWebViewConfiguration * webConfig;
設定Delegate
self.webView.navigationDelegate = self;
self.webView.UIDelegate = self;
實現webConfig
#pragma mark - accessors
-(WKWebViewConfiguration*) webConfig {
if (!_webConfig) {
_webConfig = [[WKWebViewConfigurationalloc]init];
WKUserContentController* userController = [[WKUserContentControlleralloc]init];
[userController addScriptMessageHandler:selfname:@"這裡要對應你的JavaScript Code"];
//例如:JavaScript 是 : window.webkit.messageHandlers.Sign.postMessage('abc');
//JavaScript 要Call iOS的function 必須要執行 window.webkit.messageHandlers.Sign.postMessage('abc');
//上面的abc 可以換成物件(Object)或是陣列(Array) App接到後判斷就可以轉換了
//另外記得要用try catch包起來不然一般瀏覽器會有問題
//你的Code就是下面這樣
[userController addScriptMessageHandler:selfname:@"Sign"];
_webConfig.userContentController = userController;
}
return_webConfig;
}
因為WKWebView不允許彈出視窗(alert),但是我們可以抓到彈出視窗的指令,並用原生的方式取代
/**
* web界面中有弹出警告框时调用
*
* @param webView 实现该代理的webview
* @param message 警告框中的内容
* @param frame 主窗口
* @param completionHandler 警告框消失调用
*/
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)())completionHandler {
NSLog(@"runJavaScriptAlert %@",message);
UIAlertController *alertController = [UIAlertControlleralertControllerWithTitle:message
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertActionactionWithTitle:@"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
completionHandler();
}]];
[self presentViewController:alertController animated:YEScompletion:^{}];
}
還有兩個類似的需要可以自己實現
confirm
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame
completionHandler:(void (^)(BOOL result))completionHandler
Text
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText
initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *result))completionHandler
再來抓到我們剛剛設定的JavaScript Handler
#pragma mark -WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if ([message.nameisEqualToString:@"Sign"]) {
NSLog(@"Sign");
//Do Something...
}
}
若要Call JavaScript Function 也可以
-(NSString *)getResultCode
{
NSString *exec = [NSStringstringWithFormat:@"getresultcode(\"%@\");", resultCode];
[self.webViewevaluateJavaScript:exec completionHandler:^(id response, NSError * error) {
if (error) {
NSLog(@"%@",error);
}
}];
return resultCode;
}
但好像沒辦法直接存成變數讓JavaScript使用
差不多就這樣~沒想到居然有這種用法
以前都覺得根本不會用到
但似乎很多人都希望可以Call到原生的function再傳回
因為這樣就只需要一個網頁然後就可以用同個流程
不需要再另外用原生做個畫面出來了。

請問wkwebview能夠載入local html檔案嘛? 我載出來之後似乎無法使用裡面的功能
載入Local html 跟 webview的方法一樣 [WebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"]isDirectory:NO]]]; 無法使用裡面的功能是指?哪些功能?
好謝謝大大 我在嘗試一次看看
NSString * htmlPath; NSString *htmlString; NSString *mainBundlePath = [[NSBundle mainBundle] bundlePath]; NSString *basePath = [NSString stringWithFormat:@"%@/www",mainBundlePath]; NSURL *baseURL = [NSURL fileURLWithPath:basePath isDirectory:YES]; htmlPath = [NSString stringWithFormat:@"%@/InventoryManage.html",basePath]; htmlString = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; [self.webView loadHTMLString:htmlString baseURL:baseURL]; 我是用這方法載入的 因為我還需要相對路徑 但是用了之後裡面都沒有功能
無法換頁 等等都有......用起來感覺很奇怪
所以你是想要把很多html放到app裡面去,讓它可以換頁? 我是沒這樣做過...不確定行不行耶,因為他的url一定吃不到你原始檔案路徑在哪裡 有成功請再分享一下。 讓我長一下知識~感謝嚕。
我想請問我有一個廣告banner 320*50,我用webView做呈現,但是想要點擊之後,呈現網站,webView會張開變成手機螢幕大小而不是320*50的大小,請問這樣做的到嗎
在webView上面加上點擊事件 然後addsubview 設為手機螢幕大小 這樣應該可以達到你要的要求
我有試過用tapGesture,但webView抓不到點擊,我用addsubview(webview),還是呈現出320*50的大小,請問設為螢幕大小,是加在哪裡呢??
突然想到你的webview裡面是一個網頁的URL Link嗎??? 如果是的話 webview裡面有一個shouldStartLoadWithRequest 判斷如果你的banner URL 就重新setFrame
http://ad.hodomobile.com/webad/release_320x50.php 這是我廣告banner的網址
那你就判斷如果 webview 的 shouldStartLoadWithRequest 的url 如果不是 http://ad.hodomobile.com/webad/release_320x50.php 就webview setFrame self.view.bundle 然後return YES
我是想要廣告banner以320*50在螢幕最下方做呈現,如果有點擊廣告,就會跳出廣告的網站,然後是符合手機螢幕大小,但因為用同一個webView,結果點擊了,只會出現320*50的大小....我是有試過用跳出safari瀏覽器的方法,但無法跳轉廣告網址...
你有試過我剛說的做法嗎?不行嗎???
我正在研究webview setFrame self.view.bundle....用swift語法該如何寫
還是不行誒,會變成直接全螢幕webView做顯示....
這不是你要的結果嗎......
是一開始廣告banner就全螢幕顯示了...廣告banner要以320*50在下方做呈現,點擊後的網站才以全螢幕webView顯示
webview 有一個function 叫做 shouldStartLoadWithRequest 在裡面去判斷如果 不是你廣告的網址 才setFrame 並不是一開始就setFrame
你說的是UIwebViewdelegate裡面的- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 這個嗎??
是的
還有個問題想問一下...如果要將此專案,套用在任何app上面,是要製作成一個library嗎..謝謝
要套用在任何App上 做成一個library 會比較好喔
恩恩 感謝喔!!