iOS前端交互篇-H5全嵌套

有时候项目小,为了省事,是会App内全嵌套H5的,但为了使用户体验更好,App内也会做一些修改

  • 去掉H5的水平及竖直方向的滑动条
  • 在除首页外的其他界面,左上角增加返回按钮
  • 点击左上角的返回按钮,可以按照H5的层级返回

UIWebView,非常卡

###UIWebView实现示例,缺点:实在是太卡了

#import "ViewController.h"

@interface ViewController ()
{
    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

@interface ViewController ()
{
    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已经停止了请求,所以必须加一个下拉刷新


iOS前端交互篇-H5全嵌套_第1张图片

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);
}

你可能感兴趣的:(iOS前端交互篇-H5全嵌套)