iOS前端交互篇-H5全嵌套

有时候项目小,为了省事,是会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);
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,442评论 25 707
  • 太多人把自己短板的地方当作去向别人伸出手的理所当然,这真是一种病态,难道不应该是越不堪的地方越不愿意被别人识破,然...
    心里扑通扑通乱跳阅读 462评论 2 4
  • 文/狗乖乖 每天,依然像往常一样。 早起、吃饭、上班、下班。 微信也只是在关注不得不关注的工作群,偶尔也去书法群里...
    薛静春阅读 667评论 4 3
  • 一年之计在于春,都到了烟花三月下扬州的季节,桃李纷争,百花齐放,那属于你们的花会不会开呢?快来看看三月哪些星座桃花...
    星座恋阅读 172评论 0 0
  • 服务器使用nginx时,需要使用php-fpm。所以PHP安装需要通过编译源码来安装。 下载源码包 配置 make
    iamxcc阅读 172评论 0 0