WKWebView 獲取標題+進度條+常用代理方法以及native相容處理
阿新 • • 發佈:2019-01-29
1.屬性宣告
@property (copy,nonatomic) NSString *url;
@property (copy,nonatomic) NSString *pageTitle;
@property (nonatomic, strong) WKWebView *webView; @property (nonatomic , strong) UIProgressView *processView; @property (strong,nonatomic) UIBarButtonItem *backItem;//goBack @property (strong,nonatomic) UIBarButtonItem *closeItem;//pop @property (strong,nonatomic) UILabel *errorLabel; @property (copy,nonatomic) NSString *currentUrl;//當前載入頁面的url
2.遵守協議
<WKNavigationDelegate,WKUIDelegate>
3. viewDidLoad 建立UI
- (void)viewDidLoad {
[super viewDidLoad];
self.title = self.pageTitle;
[self loadWebView];
}
-(void)loadWebView { _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight-64)]; [self.view addSubview: self.webView]; _webView.allowsBackForwardNavigationGestures = YES; _webView.navigationDelegate = self; _webView.UIDelegate = self; _webView.contentMode = UIViewContentModeScaleAspectFit; _webView.scrollView.showsVerticalScrollIndicator = NO; _webView.scrollView.showsHorizontalScrollIndicator = NO; [_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil]; [_webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL]; // process _processView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 1, kScreenWidth, 1)]; _processView.progressTintColor = MAINCOLOR; _processView.trackTintColor = [UIColor whiteColor]; [self.view addSubview:self.processView]; NSURL *url = [NSURL URLWithString:self.url]; NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url]; [self.webView loadRequest:request]; }
4. viewWillAppear 建立導航按鈕
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self setNav];
}
5. viewDidDisappear 清理快取,移除觀察者//建立導航條右側 返回 和 關閉 的按鈕 - (void)setNav { if (self.navigationController.viewControllers.count > 1) { UIButton *backBtn = [UIButton buttonWithType:(UIButtonTypeCustom)]; backBtn.frame = CGRectMake(0, 0, 50, 40); [backBtn setTitle:@" 返回" forState:UIControlStateNormal]; [backBtn.titleLabel setFont:[UIFont systemFontOfSize:16]]; [backBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [backBtn setImage:[UIImage imageNamed:@"return"] forState:UIControlStateNormal]; [backBtn setImage:[UIImage imageNamed:@"return"] forState:UIControlStateHighlighted]; [backBtn setContentHorizontalAlignment:(UIControlContentHorizontalAlignmentLeft)]; [backBtn addTarget:self action:@selector(backClick) forControlEvents:UIControlEventTouchUpInside]; [backBtn.imageView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.mas_equalTo(backBtn); make.height.mas_equalTo(@18); make.centerY.mas_equalTo(backBtn); }]; self.backItem = [[UIBarButtonItem alloc] initWithCustomView:backBtn]; UIButton *closeBtn = [UIButton buttonWithType:(UIButtonTypeCustom)]; [closeBtn setContentHorizontalAlignment:(UIControlContentHorizontalAlignmentLeft)]; closeBtn.frame = CGRectMake(0, 0, 40, 40); [closeBtn setTitle:@"關閉" forState:UIControlStateNormal]; [closeBtn.titleLabel setFont:backBtn.titleLabel.font]; [closeBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [closeBtn addTarget:self action:@selector(closeClick) forControlEvents:UIControlEventTouchUpInside]; self.closeItem = [[UIBarButtonItem alloc] initWithCustomView:closeBtn]; self.navigationItem.leftBarButtonItem = self.backItem; } }
-(void)viewDidDisappear:(BOOL)animated{
[self.webView stopLoading];
[self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
[self.webView removeObserver:self forKeyPath:@"title"];
self.webView = nil;
NSURLCache * cache = [NSURLCache sharedURLCache];
[cache removeAllCachedResponses];
[cache setDiskCapacity:0];
[cache setMemoryCapacity:0];
[super viewDidDisappear:animated];
}
6. KVO 監聽進度變化和標題變化
#pragma mark ----- KVO ----------
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"estimatedProgress"]) {
if (object == self.webView) {
[self.processView setAlpha:1.0f];
[self.processView setProgress:self.webView.estimatedProgress animated:YES];
if(self.webView.estimatedProgress >= 1.0f) {
[UIView animateWithDuration:0.3 delay:0.5 options:UIViewAnimationOptionCurveEaseOut animations:^{
[self.processView setAlpha:0.0f];
} completion:^(BOOL finished) {
[self.processView setProgress:0.0f animated:NO];
}];
}
}
else
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
else if ([keyPath isEqualToString:@"title"])
{
if (object == self.webView) {
if (self.webView.title.length != 0) {
self.title = self.webView.title;
}
}
else
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
7. 常用代理方法#pragma mark ------- WKNavigationDelegate -----
//網頁開始載入
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
self.currentUrl = webView.URL.absoluteString;
NSLog(@"currentUrl====%@",self.currentUrl);
}
//網頁載入完成
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
if (webView.backForwardList.backList.count > 0) {
self.navigationItem.leftBarButtonItems = @[self.backItem,self.closeItem];
}
}
//網頁載入失敗
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
[self.view addSubview:self.errorLabel];
}
8. 回退和關閉按鈕點選方法
#pragma mark -------- action ----------
//回退goback
- (void)backClick {
HtmlModel *model = [LocalStoreTools getHtmlModel];
if ([self.url rangeOfString:model.alarm4Dosing].location != NSNotFound &&
[self.currentUrl rangeOfString:@"index.html"].location != NSNotFound) {//用藥提醒
[self closeClick];
} else {
if ([self.webView canGoBack]) {
[self.webView goBack];
} else {
[self closeClick];
}
}
}
//關閉pop
- (void)closeClick {
if (self.presentingViewController != nil) {
[self dismissViewControllerAnimated:NO completion:nil];
} else {
[self.navigationController popViewControllerAnimated:YES];
}
}
9. native相容處理
//提示框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"確認" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
//彈出框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler(NO);
}])];
[alertController addAction:([UIAlertAction actionWithTitle:@"確認" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(YES);
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
//輸入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.text = defaultText;
}];
[alertController addAction:([UIAlertAction actionWithTitle:@"完成" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(alertController.textFields[0].text?:@"");
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
//處理 target = "__blank"
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
if (!navigationAction.targetFrame.isMainFrame) {
[webView evaluateJavaScript:@"var a = document.getElementsByTagName('a');for(var i=0;i<a.length;i++){a[i].setAttribute('target','');}" completionHandler:nil];
}
decisionHandler(WKNavigationActionPolicyAllow);
}