iOS-WKWebView的封裝

隨著iOS8推出WKWebVIew之后,很多開發(fā)者開始試著用此來替換UIWebView了。閑話少說、直接上代碼。

.h

#import <UIKit/UIKit.h>

@interface WebViewController : UIViewController
//網(wǎng)頁鏈接
@property(nonatomic,copy)NSString *urlStr;
//html內(nèi)容
@property(nonatomic,copy)NSString *content;
@end

.m

// 首先引入頭文件
#import <WebKit/WebKit.h>
static void *WKWebBrowserContext = &WKWebBrowserContext;

@interface WebViewController () <WKNavigationDelegate>
@property(nonatomic,strong)WKWebView *contentWebView;
@property(nonatomic,strong)UIProgressView *progressView;
@end

@implementation WebViewController
- (void)viewDidLoad {
    [super viewDidLoad];

    [self.view addSubview:self.contentWebView];
    [self.view addSubview:self.progressView];

    [self layoutConstraints];
    [self loadData];
}

- (void)layoutConstraints {
    [self.contentWebView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(64, 0, 0, 0));
    }];
    [self.progressView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(0);
        make.left.right.mas_equalTo(self.view);
        make.height.mas_equalTo(2);
    }];
}

- (void)loadData {
    if (self.urlStr.length) {
        NSURL* url=[NSURL URLWithString:self.urlStr relativeToURL:[NSURL URLWithString:@"http://"]];
        NSURLRequest *request =[NSURLRequest requestWithURL:url];
        [self.contentWebView loadRequest:request];
        return;
    }
    if (self.content.length) {
        [self.contentWebView loadHTMLString:self.content baseURL:nil];
        return;
    }
}

//- (void)leftBtnAction {
      // 網(wǎng)頁內(nèi)可以返回
//    if ([self.contentWebView canGoBack]) {
//        [self.contentWebView goBack];
//    }else {
//        [AppCommon popViewControllerAnimated:YES];
//    }
//}


#pragma mark - WKNavigationDelegate
//開始加載
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
    //開始加載的時(shí)候,讓加載進(jìn)度條顯示
    self.progressView.hidden = NO;
}

//網(wǎng)頁加載完成
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    // 獲取加載網(wǎng)頁的標(biāo)題
    self.titleLabel.text = self.contentWebView.title;
}
//內(nèi)容返回時(shí)調(diào)用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
}

//服務(wù)器請(qǐng)求跳轉(zhuǎn)的時(shí)候調(diào)用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
}

// 內(nèi)容加載失敗時(shí)候調(diào)用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error{
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    //如果是跳轉(zhuǎn)一個(gè)新頁面
    if (navigationAction.targetFrame == nil) {
        [webView loadRequest:navigationAction.request];
    }
    NSURL *URL = navigationAction.request.URL;
    [self dealSomeThing:URL];
    decisionHandler(WKNavigationActionPolicyAllow);
}

- (void)dealSomeThing:(NSURL *)url{
    NSString *scheme = [url scheme];
    NSString *resourceSpecifier = [url resourceSpecifier];
    if ([scheme isEqualToString:@"tel"]) {
        NSString *callPhone = [NSString stringWithFormat:@"tel://%@", resourceSpecifier];
        /// 防止iOS 10及其之后,撥打電話系統(tǒng)彈出框延遲出現(xiàn)
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:callPhone]];
        });
    }
}

//進(jìn)度條
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
}

//KVO監(jiān)聽進(jìn)度條
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    
    if ([keyPath isEqualToString:NSStringFromSelector(@selector(estimatedProgress))] && object == self.contentWebView) {
        [self.progressView setAlpha:1.0f];
        BOOL animated = self.contentWebView.estimatedProgress > self.progressView.progress;
        [self.progressView setProgress:self.contentWebView.estimatedProgress animated:animated];
        
        // Once complete, fade out UIProgressView
        if(self.contentWebView.estimatedProgress >= 1.0f) {
            [UIView animateWithDuration:0.3f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^{
                [self.progressView setAlpha:0.0f];
            } completion:^(BOOL finished) {
                [self.progressView setProgress:0.0f animated:NO];
            }];
        }
    }
    else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

#pragma mark - getters and setters
- (WKWebView *)contentWebView {
    if (!_contentWebView) {
        _contentWebView = [[WKWebView alloc] init];
        _contentWebView.backgroundColor = [UIColor whiteColor];
        _contentWebView.opaque = YES;
        //適應(yīng)你設(shè)定的尺寸
        [_contentWebView sizeToFit];
        _contentWebView.scrollView.showsVerticalScrollIndicator = NO;
        // 設(shè)置代理
        _contentWebView.navigationDelegate = self;
        //kvo 添加進(jìn)度監(jiān)控
        [_contentWebView addObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress)) options:0 context:WKWebBrowserContext];
        
        //設(shè)置網(wǎng)頁的配置文件
        WKWebViewConfiguration * Configuration = [[WKWebViewConfiguration alloc]init];
        // 此處一定要做判斷,因?yàn)槭莍OS9之后才有的方法,否則在iOS8下會(huì)崩潰
        if ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0) {
            //允許視頻播放
            Configuration.allowsAirPlayForMediaPlayback = YES;
            // 允許在線播放
            Configuration.allowsInlineMediaPlayback = YES;
            //開啟手勢(shì)觸摸 默認(rèn)設(shè)置就是NO。在ios8系統(tǒng)中會(huì)導(dǎo)致手勢(shì)問題,程序崩潰
            _contentWebView.allowsBackForwardNavigationGestures = YES;
        }
        // 允許可以與網(wǎng)頁交互,選擇視圖
        Configuration.selectionGranularity = YES;
        // web內(nèi)容處理池
        Configuration.processPool = [[WKProcessPool alloc] init];
        //自定義配置,一般用于 js調(diào)用oc方法(OC攔截URL中的數(shù)據(jù)做自定義操作)
        WKUserContentController * UserContentController = [[WKUserContentController alloc]init];
        // 是否支持記憶讀取
        Configuration.suppressesIncrementalRendering = YES;
        // 允許用戶更改網(wǎng)頁的設(shè)置
        Configuration.userContentController = UserContentController;
    }
    return _contentWebView;
}

- (UIProgressView *)progressView {
    if (!_progressView) {
        _progressView = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleDefault];
        [_progressView setTrackTintColor:[UIColor colorWithRed:240.0/255 green:240.0/255 blue:240.0/255 alpha:1.0]];
        _progressView.progressTintColor = [UIColor redColor];
    }
    return _progressView;
}

// 記得dealloc
- (void)dealloc {
    [self.contentWebView removeObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress))];
}

使用起來也是非常方便:

WebViewController *webVC = [[WebViewController alloc] init];
//網(wǎng)頁鏈接(在.h文件中已聲明)
webVC.urlStr = @"";
[self.navigationController pushViewController:webVC animated:YES];

基本使用的也就是這些方法,代碼就不發(fā)了,直接cpoy即可。
本文沒有提到,如何用WKWebView加載html本地文件,因?yàn)閕OS8根iOS9+系統(tǒng)不一樣,會(huì)單獨(dú)拿一篇文章出來。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容