有时候项目小,为了省事,是会App内全嵌套H5的,但为了使用户体验更好,App内也会做一些修改
- 去掉H5的水平及竖直方向的滑动条
- 在除首页外的其他界面,左上角增加返回按钮
- 点击左上角的返回按钮,可以按照H5的层级返回
UIWebView,非常卡
###UIWebView实现示例,缺点:实在是太卡了
#import "ViewController.h"
@interface ViewController ()<UIWebViewDelegate>
{
UIWebView *_webView;
UIButton *_backButton;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
//返回按钮
_backButton = [UIButton buttonWithType:UIButtonTypeSystem];
_backButton.frame = CGRectMake(10, 20, 20, 20);
[_backButton setTitle:@"返回" forState:UIControlStateNormal];
[_backButton addTarget:self action:@selector(back:) forControlEvents:UIControlEventTouchUpInside];
//webView
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)];
_webView.backgroundColor = [UIColor clearColor];
###1.去掉H5的水平及竖直方向的滑动条
for (UIView * views in [_webView subviews])
{
if ([views isKindOfClass:[UIScrollView class]])
{
[(UIScrollView *)views setShowsHorizontalScrollIndicator:NO];
[(UIScrollView *)views setShowsVerticalScrollIndicator:NO];
}
}
_webView.scalesPageToFit = YES;
_webView.delegate = self;
[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://licai.jyb.com/h5/home?cha_code=A90105"]]];
[self.view addSubview:_webView];
}
- (void)dealloc
{
_webView = nil;
}
#pragma mark - Actions
###3.点击左上角的返回按钮,可以按照H5的层级返回
- (void)back:(UIBarButtonItem *)btn
{
if ([_webView canGoBack])
{
[_webView goBack];
}
else
{
[self.view resignFirstResponder];
[self.navigationController popViewControllerAnimated:YES];
}
}
#pragma mark - UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
//获取当前页面的title
NSString * title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
self.title = title;
//获取当前网页的html
NSString *currentURL = webView.request.URL.absoluteString;
###2.在除首页外的其他界面,左上角增加返回按钮
if([currentURL isEqualToString:@"http://licai.jyb.com/h5/home?cha_code=A90105"])
{
self.navigationItem.leftBarButtonItem = nil;
}
else
{
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:_backButton];
}
}
1.在webView初始化时则循环去掉水平及竖直滑动条
2.每次页面加载完成,均会调用webViewDidFinishLoad代理方法,在此判断链接是否是首页,如果是首页则不显示左上角按钮,否则显示
这里非常卡顿,尤其是界面第一次加载时特别缓慢,造成的用户使用效果就是:界面显示出好一会了,左上角的按钮才会出现或者消失
3.在点击左上角返回按钮时,判断当前WebView是否可以返回,如果可以直接返回,如果不可以直接跳回首页面
WKWebView优化,流畅了非常多...
区别
1.需要导入头文件
2.没有获取title,是自己写死的
#import "ViewController.h"
#import<WebKit/WebKit.h>
@interface ViewController ()<WKNavigationDelegate>
{
WKWebView *_webView;
UIButton *_backButton;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.title = @"银行理财超市";
//返回按钮
_backButton = [UIButton buttonWithType:UIButtonTypeSystem];
_backButton.frame = CGRectMake(10, 20, 20, 20);
[_backButton setTitle:@"返回" forState:UIControlStateNormal];
[_backButton addTarget:self action:@selector(back:) forControlEvents:UIControlEventTouchUpInside];
//webView
_webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)];
//设置背景色
_webView.opaque = NO;
_webView.backgroundColor = [UIColor whiteColor];
for (UIView * views in [_webView subviews])
{
if ([views isKindOfClass:[UIScrollView class]])
{
//去掉水平方向的滑动条
[(UIScrollView *)views setShowsHorizontalScrollIndicator:NO];
//去掉垂直方向的滑动条
[(UIScrollView *)views setShowsVerticalScrollIndicator:NO];
}
}
_webView.navigationDelegate = self;
[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://licai.jyb.com/h5/home?cha_code=A90105"]]];
[self.view addSubview:_webView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void)dealloc
{
_webView = nil;
}
#pragma mark - Actions
- (void)back:(UIBarButtonItem *)btn
{
if ([_webView canGoBack])
{
[_webView goBack];
}
else
{
[self.view resignFirstResponder];
[self.navigationController popViewControllerAnimated:YES];
}
}
#pragma mark - WKNavigationDelegate
// 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
//获取当前网页的html
NSString *currentURL = webView.URL.absoluteString;
if([currentURL isEqualToString:@"http://licai.jyb.com/h5/home?cha_code=A90105"])
{
self.navigationItem.leftBarButtonItem = nil;
}
else
{
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:_backButton];
}
}
-
上面代码发现有三个问题
1.因为后续涉及了分享,分享出去的标题不能是写死的,需要获取H5的title
2.需要有进度条
3.当用户初次安装打开首页的时候(此时H5已经请求了),会弹出是否使用数据,当你未选择的时候,H5是停止请求的空白的页面,当选择了允许,但H5已经停止了请求,所以必须加一个下拉刷新
4.H5中有跳转AppStore的链接,WKWebView不会自动识别并去跳转
-
KVO用法
1.为对象属性注册观察者
observer: 观察者对象
keyPath: 被观察的属性,其不能为nil
options: 设定通知观察者时传递的属性值,是传改变前的呢,还是改变后的
context: 一些其他的需要传递给观察者的上下文信息,通常设置为nil
- (void)addObserver:(NSObject *)observer
forKeyPath:(NSString *)keyPath
options:(NSKeyValueObservingOptions)options
context:(void *)context
2.观察者接收通知,并做出处理:观察者通过实现下面的方法,完成对属性改变的响应
keyPath: 被观察的属性,其不能为nil.
object: 被观察者的对象.
change: 属性值,根据上面提到的Options设置,给出对应的属性值
context: 上面传递的context对象。
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
3.移除观察者
- (void)removeObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath
-
KVO实现获取title和进度条实现:
###KVO实现获取title和进度条
//1.注册观察者
[_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:NULL];
[_webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL];
//进度条
@property (nonatomic,strong) UIProgressView *progress;
- (UIProgressView *)progress
{
if (_progress == nil)
{
_progress = [[UIProgressView alloc]initWithFrame:CGRectMake(0, 64, [[UIScreen mainScreen] bounds].size.width, 2)];
_progress.tintColor = [UIColor colorWithRed:61.0/255.0 green:163.0/255.0 blue:225.0/255.0 alpha:0.5];
_progress.backgroundColor = [UIColor clearColor];
[self.view addSubview:_progress];
}
return _progress;
}
//2.观察者接收通知
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
//加载进度值
if ([keyPath isEqualToString:@"estimatedProgress"])
{
if (object == _webView)
{
[self.progress setAlpha:1.0f];
[self.progress setProgress:_webView.estimatedProgress animated:YES];
if(_webView.estimatedProgress >= 1.0f)
{
[UIView animateWithDuration:0.5f
delay:0.3f
options:UIViewAnimationOptionCurveEaseOut
animations:^
{
[self.progress setAlpha:0.0f];
}
completion:^(BOOL finished)
{
[self.progress setProgress:0.0f animated:NO];
}];
}
}
}
//网页title
if ([keyPath isEqualToString:@"title"])
{
if (object == _webView)
{
self.title = _webView.title;
_shareTitle = _webView.title;
}
}
}
//3.移除观察者
- (void)dealloc
{
[_webView removeObserver:self forKeyPath:@"estimatedProgress"];
[_webView removeObserver:self forKeyPath:@"title"];
}
-
刷新实现
//1.cocoaPods导入MJRefresh
#import "MJRefresh.h"
//2.添加下拉刷新方法
MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(onHeader)];
[header setTitle:@"下拉刷新" forState:MJRefreshStatePulling];
_webView.scrollView.mj_header = header;
//3.实现刷新方法(已提前在didFinishNavigation中将当前页面的url赋值给_shareString)
- (void)onHeader
{
[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:_shareString]]];
[_webView.scrollView.mj_header endRefreshing];
}
-
跳转AppStore
-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
//跳转AppStore
NSRange range = [navigationAction.request.URL.absoluteString rangeOfString:@"itunes.apple.com"];
if (range.length > 0)
{
NSLog(@"跳转");
[[UIApplication sharedApplication] openURL:navigationAction.request.URL];
}
//如果是跳转一个新页面
if (navigationAction.targetFrame == nil)
{
[webView loadRequest:navigationAction.request];
}
decisionHandler(WKNavigationActionPolicyAllow);
}