WKWebview的基本使用


在開發過程中,iOS 中實現加載 web 頁面主要有兩種控件,UIWebView 和 WKWebview,兩種控件對應具體的實現方法不同。WKWebView是蘋果公司在iOS8系統推出的,這里主要概述WebKit中更新的WKWebView控件的新特性與使用方法,以及小編在開發過程中踩的坑。

一、相比於UIWebView的優勢:

  1. 在性能、穩定性、占用內存方面有很大提升;
  2. 允許JavaScript的Nitro庫加載並使用(UIWebView中限制)
  3. 增加加載進度屬性:estimatedProgress,不用在自己寫假進度條了
  4. 支持了更多的HTML的屬性

二、WKWebview的常用屬性

@property (nullable, nonatomic, readonly, copy) NSString *title;

@property (nullable, nonatomic, readonly, copy) NSURL *URL;

@property (nonatomic, readonly, getter=isLoading) BOOL loading;
//加載進度
@property (nonatomic, readonly) double estimatedProgress;

三、WKWebview的常用方法

- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;

- (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL API_AVAILABLE(macosx(10.11), ios(9.0));

- (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;

- (nullable WKNavigation *)loadData:(NSData *)data MIMEType:(NSString *)MIMEType characterEncodingName:(NSString *)characterEncodingName baseURL:(NSURL *)baseURL API_AVAILABLE(macosx(10.11), ios(9.0));

四、WKNavigationDelegate代理的方法

#pragma mark - WKNavigationDelegate
/* 頁面開始加載 */
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
    NSLog(@"頁面開始加載");
}
/* 開始返回內容 */
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
    NSLog(@"開始返回內容");
}
/* 頁面加載完成 */
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    NSLog(@"頁面加載完成");
}
/* 頁面加載失敗 */
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{
    NSLog(@"頁面加載失敗");
}
/* 在發送請求之前,決定是否跳轉 */
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    //允許跳轉
    decisionHandler(WKNavigationActionPolicyAllow);
    //不允許跳轉
    //decisionHandler(WKNavigationActionPolicyCancel);
}
/* 在收到響應后,決定是否跳轉 */
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
    
    NSLog(@"%@",navigationResponse.response.URL.absoluteString);
    //允許跳轉
    decisionHandler(WKNavigationResponsePolicyAllow);
    //不允許跳轉
    //decisionHandler(WKNavigationResponsePolicyCancel);
}

五、小編的實例Demo

首先遵守協議:

<WKUIDelegate, WKNavigationDelegate>

其次創建一個WKWebView

#pragma mark - 創建webView
- (void)createWebView{
    
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    config.selectionGranularity = WKSelectionGranularityDynamic;
    config.allowsInlineMediaPlayback = YES;
    WKPreferences *preferences = [WKPreferences new];
    //是否支持JavaScript
    preferences.javaScriptEnabled = YES;
    //不通過用戶交互,是否可以打開窗口
    preferences.javaScriptCanOpenWindowsAutomatically = YES;
    config.preferences = preferences;
    self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:self.webView];
    
    /* 加載服務器url的方法*/
    NSString *url = @"https://www.baidu.com";
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    [self.webView loadRequest:request];
    
    self.webView.navigationDelegate = self;
    self.webView.UIDelegate = self;

}

這樣就可以在webView中正常加載百度首頁了。

不過,在開發中有時遇到網絡不佳的時候,想給用戶顯示一個加載網頁的進度,加載完成后,想再navigation中顯示網頁的標題,就需要對WKWebView的"estimatedProgress"和

"title"進行監聽了。

首先創建一個進度條

- (void)createProgressView{
    self.progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 88, SCREEN_WIDTH, 2)];
    self.progressView.progressViewStyle = UIProgressViewStyleDefault;
    self.progressView.tintColor = [UIColor blueColor];
    self.progressView.trackTintColor = [UIColor greenColor];
    [self.view addSubview:self.progressView];
}

讓webView對“進度”和“標題”進行監聽

[self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
[self.webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL];

最后,完成對KVO的回調

#pragma mark - KVO回饋
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    if ([keyPath isEqualToString:@"estimatedProgress"]) {
        double progress = _webView.estimatedProgress;
        self.progressView.alpha = 1.0f;
        [self.progressView setProgress:progress animated:YES];
        if(progress >= 1){
            [UIView animateWithDuration:0.25 delay:0.25 options:UIViewAnimationOptionCurveEaseOut animations:^{
                self.progressView.alpha = 0.0f;
            } completion:^(BOOL finished) {
                [self.progressView setProgress:0.0f animated:NO];
            }];
        }
        if ([change[@"new"] floatValue] <[change[@"old"] floatValue]) {
            return;
        }
        if ([change[@"new"]floatValue] == 1.0) {
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                
            });
        }
    }
    else if ([keyPath isEqualToString:@"title"]){
        self.title = change[@"new"];
    }
}

這樣就實現了對加載進度的顯示了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM