了解
WKWebView混合页面
适合混合页面的应用场景
常见的cookie问题
#import "WKWebViewController.h"
#import
#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height
@interface WKWebViewController ()<WKUIDelegate,WKNavigationDelegate,UITextFieldDelegate>
@property (nonatomic, strong) WKWebView *wkWebView;
@property (nonatomic, strong) WKWebViewConfiguration *wkConfig;
/*
*1.添加UIProgressView属性
*/
@property (nonatomic, strong) UIProgressView *progressView;
@end
@implementation WKWebViewController
#pragma mark - 初始化wkWebView
- (WKWebViewConfiguration *)wkConfig {
if(!_wkConfig) {
_wkConfig = [[WKWebViewConfiguration alloc] init];
_wkConfig.allowsInlineMediaPlayback = YES;
_wkConfig.allowsPictureInPictureMediaPlayback = YES;
}
return _wkConfig;
}
- (WKWebView *)wkWebView {
if(!_wkWebView) {
_wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight -64) configuration:self.wkConfig];
_wkWebView.navigationDelegate = self;
_wkWebView.UIDelegate=self;
}
return _wkWebView;
}
/*
*6.在dealloc中取消监听
*/
- (void)dealloc {
[self.wkWebView removeObserver:self forKeyPath:@"estimatedProgress"];
[self.wkWebView removeObserver:self forKeyPath:@"title"];
self.wkWebView.navigationDelegate = nil;
self.wkWebView.UIDelegate=nil;
self.wkWebView.scrollView.delegate = nil;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setupToolView];
[self setAutomaticallyAdjustsScrollViewInsets:NO];
[self.viewaddSubview:self.wkWebView];
[self.wkWebViewmas_makeConstraints:^(MASConstraintMaker*make) {
make.top.mas_equalTo(0);
make.left.right.bottom.offset(0);
}];
/*
*2.初始化progressView
*/
self.progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, 2)];
self.progressView.progressTintColor = ThemeColor;
self.progressView.trackTintColor = [UIColor whiteColor];
//设置进度条的高度,下面这句代码表示进度条的宽度变为原来的1倍,高度变为原来的1.5倍.
self.progressView.transform = CGAffineTransformMakeScale(1.0f, 1.5f);
[self.view addSubview:self.progressView];
/*
*3.添加KVO,WKWebView有一个属性estimatedProgress,就是当前网页加载的进度,所以监听这个属性。
*/
[self.wkWebView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
[self.wkWebView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL];
[self startLoad];
if(self.isPresent) {
UIButton*btn = [UIButtonbuttonWithType:UIButtonTypeCustom];
// btn.frame = CGRectMake(0, 0, 44, 44);
[btnsetImage:[UIImage imageNamed:@"navbar_icon_back"] forState:UIControlStateNormal];
[btnaddTarget:selfaction:@selector(presentBackClicked)forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:btn];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)presentBackClicked{
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
- (void)setupToolView {
// UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, kScreenHeight - 40, kScreenWidth, 40)];
// [self.view addSubview:toolBar];
//
// UIBarButtonItem *fixedSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
// UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRewind target:self action:@selector(goBackAction)];
// UIBarButtonItem *forwardButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFastForward target:self action:@selector(goForwardAction)];
// UIBarButtonItem *refreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refreshAction)];
//
// [toolBar setItems:@[backButton,fixedSpace,forwardButton,fixedSpace,refreshButton] animated:YES];
}
#pragma mark - start load web
- (void)startLoad {
NSString*urlString =self.urlStr;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
request.timeoutInterval=15.0f;
[self.wkWebViewloadRequest:request];
[self.wkWebView evaluateJavaScript:@"window.scrollTo(0,0)" completionHandler:nil];
}
#pragma mark- 监听
/*
*4.在监听方法中获取网页加载的进度,并将进度赋给progressView.progress
*/
- (void)observeValueForKeyPath:(NSString*)keyPathofObject:(id)objectchange:(NSDictionary *)changecontext:(void*)context {
if([keyPathisEqualToString:@"estimatedProgress"]) {
self.progressView.progress = self.wkWebView.estimatedProgress;
if(self.progressView.progress==1) {
/*
*添加一个简单的动画,将progressView的Height变为1.4倍
*动画时长0.25s,延时0.3s后开始动画
*动画结束后将progressView隐藏
*/
__weaktypeof(self)weakSelf =self;
[UIView animateWithDuration:0.25f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^{
weakSelf.progressView.transform=CGAffineTransformMakeScale(1.0f,1.4f);
}completion:^(BOOLfinished) {
weakSelf.progressView.hidden=YES;
}];
}
}elseif([keyPathisEqualToString:@"title"]) {
if(self.title.length==0) {
self.title=self.wkWebView.title;
}
}else{
[superobserveValueForKeyPath:keyPathofObject:objectchange:changecontext:context];
}
}
#pragma mark - WKWKNavigationDelegate Methods
/*
*5.在WKWebViewd的代理中展示进度条,加载完成后隐藏进度条
*/
//开始加载
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
NSLog(@"开始加载网页");
//开始加载网页时展示出progressView
self.progressView.hidden = NO;
//开始加载网页的时候将progressView的Height恢复为1.5倍
self.progressView.transform = CGAffineTransformMakeScale(1.0f, 1.5f);
//防止progressView被网页挡住
[self.view bringSubviewToFront:self.progressView];
}
//加载完成
- (void)webView:(WKWebView*)webViewdidFinishNavigation:(WKNavigation*)navigation
{
NSLog(@"加载完成");
NSString *injectionJSString = @"var script = document.createElement('meta');"
"script.name = 'viewport';"
"script.content=\"width=device-width, user-scalable=no\";"
"document.getElementsByTagName('head')[0].appendChild(script);";
[webViewevaluateJavaScript:injectionJSStringcompletionHandler:^(id_Nullablesuccess,NSError*_Nullableerror) {
NSLog(@"完成");
//延迟0.3s再执行刷新
dispatch_time_tdelayTime =dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3*NSEC_PER_SEC));
dispatch_after(delayTime, dispatch_get_main_queue(), ^{
[webViewevaluateJavaScript:@"window.scrollTo(0,0)" completionHandler:nil];
});
}];
}
//加载失败
- (void)webView:(WKWebView*)webViewdidFailProvisionalNavigation:(WKNavigation*)navigationwithError:(NSError*)error {
NSLog(@"加载失败");
//加载失败同样需要隐藏progressView
self.progressView.hidden = YES;
[SVProgressHUD showInfoWithStatus:@"页面加载失败,请重试"];
}
- (void)viewWillDisappear:(BOOL)animated {
[superviewWillDisappear:animated];
self.wkWebView.navigationDelegate = nil;
self.wkWebView.UIDelegate=nil;
self.wkWebView.scrollView.delegate = nil;
}
//页面跳转
- (void)webView:(WKWebView*)webViewdecidePolicyForNavigationAction:(WKNavigationAction*)navigationActiondecisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler {
//允许页面跳转
NSLog(@"%@",navigationAction.request.URL);
decisionHandler(WKNavigationActionPolicyAllow);
}
#pragma mark - Tool bar item action
- (void)goBackAction {
if([self.wkWebViewcanGoBack]) {
[self.wkWebViewgoBack];
}
}
- (void)goForwardAction {
if([self.wkWebViewcanGoForward]) {
[self.wkWebViewgoForward];
}
}
- (void)refreshAction {
[self.wkWebViewreload];
}
#pragma mark - UITextField Delegate methods
//点击完成时加载网页
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if(textField.text.length) {
NSString*urlString;
if([textField.textcontainsString:@"http://"] ||
[textField.textcontainsString:@"https://"]) {
urlString = [NSStringstringWithFormat:@"%@",textField.text];
}else{
urlString = [NSStringstringWithFormat:@"http://%@",textField.text];
}
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
request.timeoutInterval=15.0f;
[self.wkWebViewloadRequest:request];
}
return YES;
}
@end