WKWebview使用记录
0、WKWebview加載在線網頁,解決中文亂碼
NSString*str = [URL stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; NSURL * urlstr= [NSURL URLWithString:str]; [_wkWebView loadRequest:[NSMutableURLRequest requestWithURL:urlstr cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15]];上面如果包含#的url會出現問題,使用下面的方法
- (NSString *)strUTF8Encoding:(NSString *)str {return [[str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]] stringByReplacingOccurrencesOfString:@"%23" withString:@"#"]; }1、WKWebview添加手勢
UISwipeGestureRecognizer *swipe =[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction)]; swipe.delegate = self; [wkWebView addGestureRecognizer:swipe];// 允許多個手勢并發 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {return YES; }2、WKWebview禁用彈簧滑動
wkWebView.scrollView.bounces = NO;3、WKWebview被js調用
window.webkit.messageHandlers.<對象名>.postMessage(body:<數據>)//body中可以直接放js對象,也可以省略body - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {NSLog(@"JS 調用了 %@ 方法,傳回參數 %@",message.name,message.body);NSMutableDictionary *dic=[message.body objectForKey:@"body"]; }4、WKWebview調用js
NSData *data=[NSJSONSerialization dataWithJSONObject:self->object options:NSJSONWritingPrettyPrinted error:nil]; NSString *dataJson=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];NSString *dataFunc=[NSString stringWithFormat:@"generalChart(%@,%lu)",dataJson,(unsigned long)self->chartType];[self evaluateJavaScript:dataFunc completionHandler:^(id _Nullable param, NSError * _Nullable error) {}];5、wkwebview手勢返回抖屏問題:
webview側滑返回后會接著觸發html頁面添加的transition動畫導致
6、wkwebview無法跳轉App Store
- (void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler {WKNavigationActionPolicy policy =WKNavigationActionPolicyAllow;if([[navigationAction.request.URL host] isEqualToString:@"itunes.apple.com"] &&[[UIApplication sharedApplication] openURL:navigationAction.request.URL]){policy =WKNavigationActionPolicyCancel;}decisionHandler(policy); }wkwebview無法跳轉企業安裝
- (void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler {NSString *strRequest = [navigationAction.request.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];if ([strRequest containsString:@"itms-services"]) {[[UIApplication sharedApplication] openURL:[NSURL URLWithString:strRequest]];}decisionHandler(policy); }7、wkwebview監聽事件
[webView addObserver:self forKeyPath:@"canGoBack" options:NSKeyValueObservingOptionNew context:nil]; [webView addObserver:self forKeyPath:@"canGoForward" options:NSKeyValueObservingOptionNew context:nil]; [webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil]; // 進度條 [webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];// 只要觀察的對象屬性有新值就會調用 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {NSLog(@"%d, %d", self.webView.canGoForward, self.webView.canGoBack); }8、wkwebview關于iPhone X頁面適配,全屏顯示,發現頂部出現20px的空白
添加啟動圖
AppDelegate的didFinishLaunchingWithOptions方法中添加
if (@available(iOS 11.0, *)) {[[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];}webview添加
if (@available(iOS 11.0, *)) {wkWebView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; }else {self.edgesForExtendedLayout = UIRectEdgeNone; }9、wkwebview加載沙盒目錄tem中html,從mainBundle拷貝文件夾到tem
NSString *strResourcesBundle = [[NSBundle mainBundle] pathForResource:@"dist" ofType:@""];NSString *path = NSTemporaryDirectory();NSString *cacheStr=[NSString stringWithFormat:@"%@/dist",path];NSFileManager * defaultManager = [NSFileManager defaultManager];NSError *err = nil;[defaultManager copyItemAtPath: strResourcesBundle toPath:cacheStr error: &err];if(err){NSLog(@"復制初始資源文件出錯:%@", err);}NSArray *contensArr= [NSArray arrayWithArray:[defaultManager contentsOfDirectoryAtPath:cacheStr error:nil]];NSLog(@"%@",contensArr);wkwebview從tem目錄下獲取加載文件,生成url時使用fileURLWithPath
NSString *cachesPath = NSTemporaryDirectory();//tem文件目錄 NSString *cacheStr=[NSString stringWithFormat:@"%@dist/index.html",cachesPath]; NSURL *url=[NSURL fileURLWithPath: cacheStr]; if (@available(iOS 9.0, *)) {[wkWebView loadFileURL:url allowingReadAccessToURL:url]; } else {[wkWebView loadRequest:[NSURLRequest requestWithURL:url]]; }獲取沙盒地址的方法
NSString *homeDir = NSHomeDirectory();// 獲取沙盒主目錄路徑 NSString *cachesPath = NSTemporaryDirectory();//tem文件目錄 NSString *cachesPath = [NSHomeDirectory()stringByAppendingPathComponent:@"Documents"];//Documents文件目錄10、WKWebView加載不受信任的https造成錯誤:參考
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{NSLog(@"didReceiveAuthenticationChallenge");if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];completionHandler(NSURLSessionAuthChallengeUseCredential,card);} }11、WKWebView隱藏導航欄全屏加載,導航無法手勢返回問題,開始以為與setAllowsBackForwardNavigationGestures手勢沖突造成,排查后發現是導航隱藏后不支持手勢返回,添加以下代碼即可,更詳細問題參考文章第2點。
隱藏導航代碼
[self.navigationController setNavigationBarHidden:NO animated:NO];支持手勢返回代碼
self.navigationController.interactivePopGestureRecognizer.delegate = self;self.navigationController.interactivePopGestureRecognizer.enabled = YES;12、WKWebView設置setAllowsBackForwardNavigationGestures手勢返回事件監聽方法:
self.navigationController.interactivePopGestureRecognizer.delegate = self; -(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{return YES; }13、WKWebView在iOS8中使用允許手勢返回會報錯
if (@available(iOS 9.0, *)) {[wkWebView setAllowsBackForwardNavigationGestures:true]; }14、WKWebview在iOS11和iOS10中的適配,頂部會讓出狀態欄高度
if (@available(iOS 11.0, *)) {wkWebView.scrollView.contentInsetAdjustmentBehavior =UIScrollViewContentInsetAdjustmentNever; } else {self.edgesForExtendedLayout = UIRectEdgeNone; } if (@available(iOS 11.0, *)) {[[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever]; }15、設置WKWebview是否隨鍵盤上移
//設置wkwebview是否可以隨著鍵盤往上移 - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{if (isAllowScrollZoom) {return wkWebView;}else{return nil;} }16、其它應用后臺定位頂端藍條,導致wkwebview頁面向下移動
[[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(didChangeStatusBarFrame:)name:UIApplicationDidChangeStatusBarFrameNotification object:nil]; - (void)didChangeStatusBarFrame:(NSNotification *)notification {NSValue *statusBarFrameValue = [notification.userInfo valueForKey:UIApplicationStatusBarFrameUserInfoKey];NSLog(@"Status bar frame changed:%@", NSStringFromCGRect([statusBarFrameValue CGRectValue]));wkWebView.frame=CGRectMake(0.0f, 0.0f, self.view.frame.size.width, self.view.frame.size.height); }17、wkwebview在iOS12中鍵盤彈起頁面不收回問題
/// 監聽將要彈起[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardShow) name:UIKeyboardWillShowNotification object:nil];/// 監聽將要隱藏[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardHidden) name:UIKeyboardWillHideNotification object:nil]; //iOS12中鍵盤彈起頁面不收回問題 #pragma mark - addObserverKeyboard /// 鍵盤將要彈起 - (void)keyBoardShow {CGPoint point = wkWebView.scrollView.contentOffset;keyBoardPoint = point; } /// 鍵盤將要隱藏 - (void)keyBoardHidden {wkWebView.scrollView.contentOffset = keyBoardPoint; }18、wkwebview加載document目錄下的文件
-(NSString *)temPathWithPath:(NSString *)path { // NSString *cachesPath = NSTemporaryDirectory();//tem文件目錄 // NSString *cacheStr=[NSString stringWithFormat:@"%@%@",cachesPath,path];NSString *cachesPath = [NSHomeDirectory()stringByAppendingPathComponent:@"Documents"];NSString *cacheStr=[NSString stringWithFormat:@"%@/%@",cachesPath,path];return cacheStr; } NSString* webViewUrl=[[WBQmapHandle sharedQmapHandle]temPathWithPath:@"App/dist/index.html"];NSString* accessUrl = [[WBQmapHandle sharedQmapHandle]temPathWithPath:@"App/dist"];NSURL *url=[NSURL fileURLWithPath:webViewUrl];NSURL *aurl = [NSURL fileURLWithPath:accessUrl]; // 權限,目錄文件夾,不寫訪問不到資源if (@available(iOS 9.0, *)) {[wkWebView loadFileURL:url allowingReadAccessToURL:aurl];} else {[wkWebView loadRequest:[NSURLRequest requestWithURL:url]];}19、wkwebview注入js文件到web
NSString *filePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"bridge.js"]; NSString *jsString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; NSLog(@"讀取的js:%@", jsString); NSMutableString *javascript = [NSMutableString string]; [javascript appendString:jsString]; WKUserScript *noneSelectScript = [[WKUserScript alloc] initWithSource:javascript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];20、wkwebview支持橫豎屏切換
單頁面支持旋轉參考1、參考2
當進入其他頁面翻轉屏幕后返回該頁面要刷新當前頁面frame布局
- (void)viewWillAppear:(BOOL)animated {[super viewWillAppear:animated];[self refreshWkWebViewFrame]; }其他要注意的,如果導航欄出現黑線框,布局時需要動態判斷狀態欄高度
CGRect rectStatus = [[UIApplication sharedApplication] statusBarFrame]; if(([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)){//橫屏NSLog(@"橫屏");_wkWebView = [[WKWebView alloc]initWithFrame:CGRectMake(0.0f, rectStatus.size.height+44, self.view.frame.size.width, self.view.frame.size.height-rectStatus.size.height-44)];}else{//豎屏NSLog(@"豎屏");_wkWebView = [[WKWebView alloc]initWithFrame:CGRectMake(0.0f, rectStatus.size.height+20, self.view.frame.size.width, self.view.frame.size.height-rectStatus.size.height-20)]; }21、wkwebview混合開發進入后臺頁面白屏解決方案
- (void)applicationDidBecomeActive:(UIApplication *)application {// 進入前臺前先調用判斷wkwebview是否白屏,從新初始化wkwebviewUIViewController* currentView = self.window.visibleViewController;if ([[currentView class] isSubclassOfClass:[HomeViewController class]]) {[(HomeViewController*)currentView resetWindown];} } -(void)resetWindown {// 如果當前頁面進入后臺后白屏重新初始化webview, 延時為了避免首次啟動重復調用初始化dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{if (wkWebView && [self isBlankView:self.view]) {[self initWebview];}}); } // 判斷是否白屏 // 參考文章https://www.jianshu.com/p/de67f5a752b6 - (BOOL)isBlankView:(UIView*)view { // YES:blankClass wkCompositingView =NSClassFromString(@"WKCompositingView");if ([view isKindOfClass:[wkCompositingView class]]) {return NO;}for(UIView *subView in view.subviews) {if (![self isBlankView:subView]) {return NO;}}return YES; }22、wkwebview加載本地html帶hash路由無效果
fileURLWithPath會把#和?進行轉碼導致加載不出頁面,改用下面代碼進行手動拼接即可,核心代碼如下處理
完整加載本地html代碼如下
-(void)reloadWebview{NSFileManager *mgr = [NSFileManager defaultManager];NSArray *subpaths = [mgr subpathsAtPath:[[WBQmapHandle sharedQmapHandle]temPathWithPath:@"App"]];NSString *archiveName = [subpaths count] ? [subpaths objectAtIndex:0] : @"dist";if ([[WBQmapHandle sharedQmapHandle]temIsFileExist:[NSString stringWithFormat:@"App/%@/index.html", archiveName]]) {_webViewUrl=[[WBQmapHandle sharedQmapHandle]temPathWithPath:[NSString stringWithFormat:@"App/%@/index.html", archiveName]];_accessUrl = [[WBQmapHandle sharedQmapHandle]temPathWithPath:[NSString stringWithFormat:@"App/%@", archiveName]];[self loadWebviewUrl:_webViewUrl];} } -(NSString *)getWebviewUrl: (NSString *)path {return [NSString stringWithFormat:@"%@?#/%@", _webViewUrl, path]; } -(void)loadWebviewUrl:(NSString *)webViewUrl {NSString *htmlPath = [NSString stringWithFormat:@"file://%@", webViewUrl];NSURL *url=[NSURL URLWithString:htmlPath];NSURL *aurl = [NSURL fileURLWithPath:_accessUrl];if (@available(iOS 9.0, *)) {[wkWebView loadFileURL:url allowingReadAccessToURL:aurl];} else {[wkWebView loadRequest:[NSURLRequest requestWithURL:url]];} }23、wkwebview刪除緩存
- (void)deleteWebCache {/*在磁盤緩存上。WKWebsiteDataTypeDiskCache,html離線Web應用程序緩存。WKWebsiteDataTypeOfflineWebApplicationCache,內存緩存。WKWebsiteDataTypeMemoryCache,本地存儲。WKWebsiteDataTypeLocalStorage,CookiesWKWebsiteDataTypeCookies,會話存儲WKWebsiteDataTypeSessionStorage,IndexedDB數據庫。WKWebsiteDataTypeIndexedDBDatabases,查詢數據庫。WKWebsiteDataTypeWebSQLDatabases*/// NSArray * types=@[WKWebsiteDataTypeDiskCache,WKWebsiteDataTypeOfflineWebApplicationCache, WKWebsiteDataTypeMemoryCache,WKWebsiteDataTypeIndexedDBDatabases,WKWebsiteDataTypeWebSQLDatabases];//// NSSet *websiteDataTypes= [NSSet setWithArray:types];NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{}]; }持續更新中…
總結
以上是生活随笔為你收集整理的WKWebview使用记录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 秒启万台主机,腾讯云云硬盘数据调度架构演
- 下一篇: ORACLE MERGE INTO语句,