精华内容
下载资源
问答
  • 使用wkwebview 加载淘宝页面 比浏览器要 大神们谁有什么解决的办法
  • 我们开发详情页面,有的时候需要计算webView或者WKWebView的高度,然后再计算scrollView的高度,把webView放到scrollView上面。但是计算webView高度这个过程很耗费时间,原因是以下代理,网页彻底加载完才会计算出来...

    我们开发详情页面,有的时候需要计算webView或者WKWebView的高度,然后再计算scrollView的高度,把webView放到scrollView上面。但是计算webView高度这个过程很耗费时间,原因是以下代理,网页彻底加载完才会计算出来高度,我们需要的是先算出高度,先出现网页的文字,至于网页的图片,可以慢慢缓存显示全。这样不至于白屏时间过长。


    - (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation

    {

        /**计算高度*/

        dispatch_async(dispatch_get_global_queue(0,0), ^{

            [_webView evaluateJavaScript:@"document.documentElement.offsetHeight" completionHandler:^(id_Nullable result, NSError *_Nullable error) {

                //获取webView高度

                CGRect frame = _webView.frame;

                frame.size.height = [result doubleValue] + 50;

                _webView.frame = frame;

                _scrollViewHeight = 220 + _webView.height;

                _scrollView.contentSize = CGSizeMake(kScreenWidth, _scrollViewHeight);

            }];

        });

    }


    注:上边的代理被楼主弃用,太耗费时间了。取而代之用下面的方法:(用的WKWebView举例说明的)

    第一步:添加观察者

    [_webView.scrollViewaddObserver:selfforKeyPath:@"contentSize"options:NSKeyValueObservingOptionNewcontext:nil];


    第二步:观察者监听webViewcontentSize变化

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

        if ([keyPathisEqualToString:@"contentSize"]) {

            dispatch_async(dispatch_get_global_queue(0,0), ^{

                //document.documentElement.scrollHeight

                //document.body.offsetHeight

                [_webViewevaluateJavaScript:@"document.documentElement.offsetHeight"completionHandler:^(id_Nullable result, NSError * _Nullable error) {

                    CGRect frame =_webView.frame;

                    frame.size.height = [resultdoubleValue] + 50;

                    _webView.frame = frame;

                    _scrollViewHeight =220 + _webView.height;

                    _scrollView.contentSize =CGSizeMake(kScreenWidth,_scrollViewHeight);

                }];

            });

        }

    }


    第三步:移除观察者

    - (void)dealloc

    {

        [_webView.scrollViewremoveObserver:selfforKeyPath:@"contentSize"];

    }


    总结:以上这个方法,不能说特别快速加载,但是在我这里速度至少提升了几倍。我也在找更好的优化方法,比如缓存等等。有知道的更好的方法的小伙伴,欢迎贴出来,楼主感激!!!



    展开全文
  • WKWebView,wkwebview加载HTML字符串

    千次阅读 2018-06-11 12:06:00
    网页加载速度也有提升,但是并不像内存那样提升那么多。下面列举一些其它的优势: 更多的支持HTML5的特性 官方宣称的高达60fps的滚动刷新率以及内置手势 Safari相同的JavaScript引擎 将...

    wkwebview使用时需要导入(#import <WebKit/WebKit.h>)

    WKWebView从iOS8才有,毫无疑问WKWebView将逐步取代笨重的UIWebView。通过简单的测试即可发现UIWebView占用过多内存,且内存峰值更是夸张。WKWebView网页加载速度也有提升,但是并不像内存那样提升那么多。下面列举一些其它的优势:

    • 更多的支持HTML5的特性
    • 官方宣称的高达60fps的滚动刷新率以及内置手势
    • Safari相同的JavaScript引擎
    • 将UIWebViewDelegate与UIWebView拆分成了14类与3个协议(官方文档说明)
    • 另外用的比较多的,增加加载进度属性:estimatedProgress

    常用属性:

    @property (nonatomic, readonly) BOOL canGoBack;
    @property (nonatomic, readonly) BOOL canGoForward;
    - (WKNavigation *)goBack;
    - (WKNavigation *)goForward;
    - (WKNavigation *)reload;
    - (void)stopLoading;
    
    /*  
      reloadFromOrigin会比较网络数据是否有变化,没有变化则使用缓存,否则从新请求。
      goToBackForwardListItem:比向前向后更强大,可以跳转到某个指定历史页面
    */
    - (WKNavigation *)reloadFromOrigin;
    - (WKNavigation *)goToBackForwardListItem:(WKBackForwardListItem *)item;
    // 是否允许左右划手势导航,默认不允许
    @property (nonatomic) BOOL allowsBackForwardNavigationGestures;
    // 加载进度 0 ~ 1
    @property (nonatomic, readonly) double estimatedProgress;
    
    @property (nullable, nonatomic, readonly, copy) NSString *title;
    // 访问历史列表,可以通过前进后退按钮访问,或者通过goToBackForwardListItem函数跳到指定页面
    @property (nonatomic, readonly, strong) WKBackForwardList *backForwardList;

    常用方法:

    - (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;
    - (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL
    - (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
    - (nullable WKNavigation *)loadData:(NSData *)data MIMEType:(NSString *)MIMEType characterEncodingName:(NSString *)characterEncodingName baseURL:(NSURL *)baseURL
    
    
    #pragma mark - WKNavigationDelegate
    // 页面开始加载时调用
    - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
    
    }
    // 当内容开始返回时调用
    - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
    
    }
    // 页面加载完成之后调用
    - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    
    }
    // 页面加载失败时调用
    - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{
    
    }
    // 接收到服务器跳转请求之后调用
    - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
    
    }
    // 在收到响应后,决定是否跳转
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
    
        NSLog(@"%@",navigationResponse.response.URL.absoluteString);
        //允许跳转
        decisionHandler(WKNavigationResponsePolicyAllow);
        //不允许跳转
        //decisionHandler(WKNavigationResponsePolicyCancel);
    }
    // 在发送请求之前,决定是否跳转
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    
         NSLog(@"%@",navigationAction.request.URL.absoluteString);
        //允许跳转
        decisionHandler(WKNavigationActionPolicyAllow);
        //不允许跳转
        //decisionHandler(WKNavigationActionPolicyCancel);
    }
    
    
    
    #pragma mark - WKUIDelegate
    // 创建一个新的WebView
    - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{
        return [[WKWebView alloc]init];
    }
    // 输入框
    - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{
        completionHandler(@"http");
    }
    // 确认框
    - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{
        completionHandler(YES);
    }
    // 警告框
    - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
        NSLog(@"%@",message);
        completionHandler();
    }

     网页加载进度监听:

    // 注册观察者
    [self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
    
    // 监听网页加载进度
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
        [self.progressView setProgress:self.webView.estimatedProgress animated:YES];
        
        if (self.progressView.progress == 1) {
            self.progressView.hidden = YES;
        }
    
    }
    
    // 开始加载
    - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
        self.progressView.hidden = NO;
        
    }
    
    // 加载完成
    - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
        self.progressView.hidden = YES;
        
    }
    
    // 加载失败
    - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error{
        self.progressView.hidden = YES;
        
    }

    js调动oc

    首先需要添加WKScriptMessageHandler协议
    
    // 为了避免循环引用,在viewWillAppear中添加js事件,在viewDidDisappear中移除
    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
    // 配置js环境
    WKUserContentController *userCC = self.webView.configuration.userContentController;
    // 添加js事件 
    [userCC addScriptMessageHandler:self name:@"onClickName"];
    
    }
    
    // 处理js交互
    // 前端必须使用window.webkit.messageHandlers.注册的方法名.postMessage({body:传输的数据}
    /* 示例
    window.webkit.messageHandlers.uploadRebate.postMessage({platName:data.platName,platId:data.platId,name:data.name,id:data.id})
    前端给的方法名为uploadRebate,给的参数是一个字典
    */
    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
        NSLog(@"拦截的方法名%@ , 拦截的方法传过来的参数%@", message.name, message.body);
        
    }
    
    - (void)viewDidDisappear:(BOOL)animated {
        [super viewDidDisappear:animated];{
        
        // 移除js
        [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"onClickName"];
    }

    oc调用js

    // 加载完成
    - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
        
        //say()是JS方法名,completionHandler是异步回调block
        [self.webView evaluateJavaScript:@"say()" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
            NSLog(@"%@",result);
        }];
    }

    清除缓存

    // 清除缓存
    +(void)deleteWebCache{
       
        if ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0) {
            /*
             在磁盘缓存上。
             WKWebsiteDataTypeDiskCache,
             html离线Web应用程序缓存。
             WKWebsiteDataTypeOfflineWebApplicationCache,
             内存缓存。
             WKWebsiteDataTypeMemoryCache,
             本地存储。
             WKWebsiteDataTypeLocalStorage,
             Cookies
             WKWebsiteDataTypeCookies,
             会话存储
             WKWebsiteDataTypeSessionStorage, IndexedDB数据库。
             WKWebsiteDataTypeIndexedDBDatabases,
             查询数据库。
             WKWebsiteDataTypeWebSQLDatabases
             */
            NSArray * types=@[WKWebsiteDataTypeCookies,WKWebsiteDataTypeLocalStorage];
            NSSet *websiteDataTypes= [NSSet setWithArray:types];
            NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
            [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{
                
            }];
     
        } else {
            
            // 清楚Library目录下的 Cookies文件夹与WebKit文件夹里面的内容
            NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
            
            NSString *cookiesFolderPath = [libraryPath stringByAppendingString:@"/Cookies"];
            NSError *errors;
            [[NSFileManager defaultManager] removeItemAtPath:cookiesFolderPath error:&errors];
            
            NSString *WebKit = [libraryPath stringByAppendingString:@"/WebKit"];
            NSError *error;
            [[NSFileManager defaultManager] removeItemAtPath:WebKit error:&error];
       
        }
    
    }

    页面导航逐级返回

    if ([webV canGoBack]) {
                
      [webV goBack];
                
    }else{
                
      [self.navigationController popViewControllerAnimated:YES];
    }

    监听网页链接的变化

    有时候监听跳转的代理不走,不知道为什么,只能用kvo先解决一下了

    [_webViews addObserver:self forKeyPath:@"URL" options:NSKeyValueObservingOptionNew context:nil];
    
    -(void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context{
    
    NSLog(@"url == %@",_webViews.URL.absoluteString);
    
    }
    

    小知识,wkwebview播放背景音乐

    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    
    config.allowsInlineMediaPlayback = YES;
    
    config.mediaPlaybackRequiresUserAction = false;
    
    wkWebView=[[WKWebView alloc] initWithFrame:rect configuration:config];
    
    wkWebView.UIDelegate=self;
    
    wkWebView.navigationDelegate=self;

     

    wkwebview加载HTML字符串

    - (void)setWKWeb{
        //js脚本 (脚本注入设置网页样式)
        NSString *jScript = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
        //注入
        WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
        WKUserContentController *wkUController = [[WKUserContentController alloc] init];
        [wkUController addUserScript:wkUScript];
        //配置对象
        WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
        wkWebConfig.userContentController = wkUController;
        //改变初始化方法 (这里一定要给个初始宽度,要不算的高度不对)
        WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, BKSCREEN_WIDTH - 30, 0) configuration:wkWebConfig];
        webView.scrollView.bounces = NO;
        _wkWeb = webView;
        _wkWeb.navigationDelegate = self;
        
    }
    
    //网页加载完成
    //页面加载完后获取高度,设置脚,注意,控制器里不能重写代理方法,否则这里会不执行
    - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
        
        //    document.body.scrollHeight(加载HTML源站用这个)   document.body.offsetHeight;(加载HTML字符串)
        [webView evaluateJavaScript:@"document.body.offsetHeight" completionHandler:^(id Result, NSError * error) {
            NSString *heightStr = [NSString stringWithFormat:@"%@",Result];
            
            //必须加上一点
            CGFloat height = heightStr.floatValue+15.00;
            //网页加载完成
            NSLog(@"新闻加载完成网页高度:%f",height);
            self.wkWebHeigh = height;
            [self.tableV reloadData];
        }];
    }

    补全网页代码,设置图片适应屏幕宽度(遍历网页中所有的图片,设置$img[p].style.width = '100%%')

    NSString *htmlString = [NSString stringWithFormat:@"<html> \n"
                                    "<head> \n"
                                    "<style type=\"text/css\"> \n"
                                    "body {font-size:15px;}\n"
                                    "</style> \n"
                                    "</head> \n"
                                    "<body>"
                                    "<script type='text/javascript'>"
                                    "window.onload = function(){\n"
                                    "var $img = document.getElementsByTagName('img');\n"
                                    "for(var p in  $img){\n"
                                    " $img[p].style.width = '100%%';\n"
                                    "$img[p].style.height ='auto'\n"
                                    " let height = document.body.offsetHeight;\n"   "window.webkit.messageHandlers.imagLoaded.postMessage(height);\n"
                                    "}\n"
                                    "}"
                                    "</script>%@"
                                    "</body>"
                                    "</html>", self.baseModel.desc];
            BKLog(@"HTML字符串:%@", htmlString);
            [self.wkWeb loadHTMLString:htmlString baseURL:nil];

    计算高度方法二:(在 HTML DOM 中 Event 有个函数 onload 是用于一张页面或一幅图像完成加载时所执行的,我们需要监听所有的 img标签 或 body标签,然后在这个方法里发个消息给 WebKit 然后进行拦截)

    " let height = document.body.offsetHeight;\n"   "window.webkit.messageHandlers.imagLoaded.postMessage(height);\n"

    上面补全网页代码中这两行就是监听发送高度通知,然后我们只需要拦截imagLoaded这个js方法就可以拿到(document.body.offsetHeight)也就是网页的高度了

    [self.wkWeb.configuration.userContentController addScriptMessageHandler:self name:@"imagLoaded"];
    
    
    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
        NSLog(@"拦截的方法名%@ , 拦截的方法传过来的参数%@", message.name, message.body);
        if ([message.name isEqualToString:@"imagLoaded"]) {
            CGFloat height = [message.body floatValue];
            self.wkWebHeigh = height;
            [self.tableV reloadData];
        }
    }

    计算高度方法三:监听网页的加载状态(loading),比监听"scrollView.contentSize"属性调用的少

    [self.wkWeb addObserver:self forKeyPath:@"loading" options:NSKeyValueObservingOptionNew context:nil];
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
        
        if ([keyPath isEqualToString:@"loading"]) {
            [self.wkWeb evaluateJavaScript:@"document.body.scrollHeight" completionHandler:^(id Result, NSError * error) {
                NSString *heightStr = [NSString stringWithFormat:@"%@",Result];
                
                //必须加上一点
                CGFloat height = heightStr.floatValue;
                if (height == 0) {
                    return ;
                }
                //网页加载完成
                NSLog(@"新闻加载完成网页高度:%f",height);
                self.wkWebHeigh = height;
                [self.tableV reloadData];
            }];
            
        }
    }

     

     

     

     

     

     

     

    转载于:https://my.oschina.net/yejiexiaobai/blog/1828053

    展开全文
  • 简介 如果项目支持iOS7之前的系统版本的话,可以做个系统判断,这里就不介绍了,这里还是推荐使用WKWebView,先...这个自iOS2开始使用的网页加载器一直是开发的心病:加载速度慢,占用内存多,优化困难。如果加载网页多

    简介

    如果项目支持iOS7之前的系统版本的话,可以做个系统判断,这里就不介绍了,这里还是推荐使用WKWebView,先介绍下使用这个的好处,然后介绍使用UIWebView和WKWebView加载进度条的代码。

    开发App的过程中,常常会遇到在App内部加载网页,通常用UIWebView加载。这个自iOS2开始使用的网页加载器一直是开发的心病:加载速度慢,占用内存多,优化困难。如果加载网页多,还可能因为过量占用内存而给系统kill掉。各种优化的方法效果也不那么明显。


    iOS8以后,苹果推出了新框架Wekkit,提供了替换UIWebView的组件WKWebView。各种UIWebView的问题没有了,速度更快了,占用内存少了,一句话,WKWebView是App内部加载网页的最佳选择!

    先看下 WKWebView的特性:

    1. 在性能、稳定性、功能方面有很大提升(最直观的体现就是加载网页是占用的内存,模拟器加载百度与开源中国网站时,WKWebView占用23M,而UIWebView占用85M);
    2. 允许JavaScript的Nitro库加载并使用(UIWebView中限制);
    3. 支持了更多的HTML5特性;
    4. 高达60fps的滚动刷新率以及内置手势;
    5. 将UIWebViewDelegate与UIWebView重构成了14类与3个协议(查看苹果官方文档);


    一、首先介绍UIWebview进度条的使用方法

    不同于WKWebview,wk是有自己的加载进度值的,我们可以直接通过kvo检测到,并显示到进度条内。

     

    但如果我们为了适配ios7,只能使用UIWebview了,这里的加载进度,就比较尴尬了

     

    所以我们的实现方式就是:模拟进度-俗称假进度。

    实现原理:

    自定义一个UIView的进度条,添加到Nav下方,给予两个方法:

    1、startLoadingAnimation  开始加载

    2、endLoadingAnimation  结束加载

     

    开始加载,先动画模拟一个0.4s的加载,加载宽度为0.6倍屏幕宽度,动画结束,再0.4s实现,总共0.8倍的屏幕宽度。

    结束动画,动画模拟1.0倍数的屏幕宽度,实现全部加载完成,并最后隐藏掉进度条。

     

    代码:

    .h文件

    复制代码
    #import <UIKit/UIKit.h>
    
    @interface WebviewProgressLine : UIView
    
    //进度条颜色
    @property (nonatomic,strong) UIColor  *lineColor;
    
    //开始加载
    -(void)startLoadingAnimation;
    
    //结束加载
    -(void)endLoadingAnimation;
    
    @end
    复制代码

     

    .m文件

    复制代码
    #import "WebviewProgressLine.h"
    
    @implementation WebviewProgressLine
    
    -(instancetype)initWithFrame:(CGRect)frame{
        self = [super initWithFrame:frame];
        if (self) {
            self.hidden = YES;
            self.backgroundColor = [UIColor whiteColor];
        }
        return self;
    }
    
    -(void)setLineColor:(UIColor *)lineColor{
        _lineColor = lineColor;
        self.backgroundColor = lineColor;
    }
    
    -(void)startLoadingAnimation{
        self.hidden = NO;
        self.width = 0.0;
        
        __weak UIView *weakSelf = self;
        [UIView animateWithDuration:0.4 animations:^{
            weakSelf.width = KScreenWidth * 0.6;
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:0.4 animations:^{
                weakSelf.width = KScreenWidth * 0.8;
            }];
        }];
        
        
    }
    
    -(void)endLoadingAnimation{
        __weak UIView *weakSelf = self;
        [UIView animateWithDuration:0.2 animations:^{
            weakSelf.width = KScreenWidth;
        } completion:^(BOOL finished) {
            weakSelf.hidden = YES;
        }];
    }
    
    @end
    复制代码

     

    webview页面使用:

    复制代码
    #import "webviewViewController.h"
    #import "WebviewProgressLine.h"
    
    @interface webviewViewController ()<UIWebViewDelegate>
    @property (nonatomic,strong) UIWebView  *webview;
    @property (nonatomic,strong) WebviewProgressLine  *progressLine;
    
    @end
    
    @implementation webviewViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor whiteColor];
        
        self.webview = [[UIWebView alloc] initWithFrame:self.view.frame];
        self.webview.delegate = self;
        [self.view addSubview:self.webview];
        
        self.progressLine = [[WebviewProgressLine alloc] initWithFrame:CGRectMake(0, 64, KScreenWidth, 3)];
        self.progressLine.lineColor = [UIColor redColor];
        [self.view addSubview:self.progressLine];
        
        
        NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
        [self.webview loadRequest:[NSURLRequest requestWithURL:url]];
        
    }
    
    -(void)webViewDidStartLoad:(UIWebView *)webView{
        [self.progressLine startLoadingAnimation];
    }
    
    -(void)webViewDidFinishLoad:(UIWebView *)webView{
        [self.progressLine endLoadingAnimation];
    }
    
    -(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
        [self.progressLine endLoadingAnimation];
    }
    复制代码


    二、介绍WKWebview进度条使用方法

    iOS8之后就可以使用WKWebview了

    1.添加UIProgressView属性

    @property (nonatomic, strong) WKWebView *wkWebView;
    @property (nonatomic, strong) UIProgressView *progressView;

    2.初始化progressView

    - (void)viewDidLoad {
        [super viewDidLoad];    
        //进度条初始化
        self.progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 20, [[UIScreen mainScreen] bounds].size.width, 2)];
        self.progressView.backgroundColor = [UIColor blueColor];
        //设置进度条的高度,下面这句代码表示进度条的宽度变为原来的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];

    4.在监听方法中获取网页加载的进度,并将进度赋给progressView.progress

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
        if ([keyPath isEqualToString:@"estimatedProgress"]) {
            self.progressView.progress = self.wkWebView.estimatedProgress;
            if (self.progressView.progress == 1) {
                /*
                 *添加一个简单的动画,将progressView的Height变为1.4倍,在开始加载网页的代理中会恢复为1.5倍
                 *动画时长0.25s,延时0.3s后开始动画
                 *动画结束后将progressView隐藏
                 */
                __weak typeof (self)weakSelf = self;
                [UIView animateWithDuration:0.25f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^{
                    weakSelf.progressView.transform = CGAffineTransformMakeScale(1.0f, 1.4f);
                } completion:^(BOOL finished) {
                    weakSelf.progressView.hidden = YES;
    
                }];
            }    
        }else{
            [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
        }
    }

    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 *)webView didFinishNavigation:(WKNavigation *)navigation {
        NSLog(@"加载完成");
        //加载完成后隐藏progressView
        //self.progressView.hidden = YES;
    }
    
    //加载失败
    - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
        NSLog(@"加载失败");
        //加载失败同样需要隐藏progressView
        //self.progressView.hidden = YES;
    }

    6.在dealloc中取消监听

    - (void)dealloc {
        [self.wkWebView removeObserver:self forKeyPath:@"estimatedProgress"];
    }

    三、总结

    一般h5页面有联系我们然后点击拨打电话的功能,在使用的时候发现了UIWebView加载的H5,可以调用;但是WKWebView就是不行,解决WKWebView加载H5页面,无法调用拨打电话功能的问题

    H5的拨打电话代码是

    <a href="tel:13112345678">移动WEB页面JS一键拨打号码咨询功能</a>

    解决的方法:在WKWebView的WKNavigationDelegate代理方法处理

    解决代码如下:

    // 处理拨打电话以及Url跳转等等

    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {

        NSURL *URL = navigationAction.request.URL;

        NSString *scheme = [URLscheme];

        if ([schemeisEqualToString:@"tel"]) {

            NSString *resourceSpecifier = [URLresourceSpecifier];

            NSString *callPhone = [NSStringstringWithFormat:@"telprompt://%@", resourceSpecifier];

            /// 防止iOS 10及其之后,拨打电话系统弹出框延迟出现

            dispatch_async(dispatch_get_global_queue(0,0), ^{

                [[UIApplicationsharedApplication]openURL:[NSURLURLWithString:callPhone]];

            });

        }

        decisionHandler(WKNavigationActionPolicyAllow);

    }


    demo的地址:

    https://github.com/joinxinxu/WebLoad.git


    展开全文
  • 最近排查android webview https的发热耗电和加载速度慢问题问题:H5页面发热耗电排查:通过android studio profiler 查看CPU消耗曲线,发现静置情况下webview轮播图波浪式消耗CPU,且峰值高达45%。因为WebView加载的...

    最近排查android webview https的发热耗电和加载速度慢问题
    问题:H5页面发热耗电
    排查:通过android studio profiler 查看CPU消耗曲线,发现静置情况下webview轮播图波浪式消耗CPU,且峰值高达45%。因为WebView加载的H5页面中的动画导致的是整个WebView的重绘。
    解决:换用X5内核,没能解决CPU峰值高问题。发现轮播图是JQUERY写的,换用纯js实现轮播图,问题解决,CPU峰值降为8%。

    问题:https 加载速度慢
    排查:首先排查https加速,启用session ticket可以减少TLS的握手连接,等同http方式的加载速度。
    解决:若没有启用就执行启动。主要是安装proxy抓包工具的证书,使能够抓包https,才能查看是否启用session ticket。及wireshark工具,查看底层网络tcpip连接的https tls握手交互连接步骤顺序时间等。有工具才能查看数据,通过数据排查加速效果。

    问题:H5首次加载速度慢
    排查:主要通过webview 的 WebViewClient回调方法:onPageStarted开始加载,onLoadResource加载资源,onPageFinished加载结束。都打印log进行排查时间消耗。
    解决:1、同比更换X5内核,可以达到提高30%速度。2、JS脚本延迟加载,可以加速渲染速度,同比提高40%。3、setBlockNetworkImage使用,可以逐步显示,先渲染文本再渲染图片,视觉上有加速效果。4、php动态程序改为服务器端先生成html。等组合方式共同解决问题。

    转载于:https://blog.51cto.com/ljianbing/2121195

    展开全文
  • WKWebview

    2017-03-28 10:32:01
    这个自iOS2开始使用的网页加载器一直是开发的心病:加载速度慢,占用内存多,优化困难。如果加载网页多,还可能因为过量占用内存而给系统kill掉。各种优化的方法效果也不那么明显(点击查看常用优化方法)。 iOS8...
  • WKWebView

    2018-10-08 17:11:00
    An object that displays ...WKWebView属于WebKit.framework框架,Apple在WWDC 2014中随iOS 8和OS X 10.10提出来的,为了解决UIWebView加载速度慢、占用内存大的问题。 使用UIWebView加载网页的时候,内存...
  • iOS WKWebView 获得title和加载进度

    千次阅读 2017-12-13 15:16:44
    iOS8后,苹果推出了新框架Webkit,提供了替换UIWebView的组件WKWebView,相比于UIWebView,好处多多,速度更快了,占用内存少了。 2、基本使用使用方法和UIWebView大同小异,具体使用可以参考使用WKWebView替换...
  • WKWebView详解

    2016-11-14 14:51:00
    WKWebView是在Apple的WWDC 2014随iOS 8和OS X 10.10出来的,是为了解决UIWebView加载速度慢、占用内存大的问题。使用UIWebView加载网页的时候,我们会发现内存会无限增长,还有内存泄漏的问题存在。WebKit中更新的...
  • WKWebview详解

    千次阅读 2018-05-15 17:07:28
    而这个自iOS2.0开始使用的Web容器一直是开发的心病:加载速度慢,占用内存多,优化困难。如果加载网页多,还可能因为过量占用内存而给系统kill掉。各种优化的方法效果也不那么明显,常见的优化缓存方式:1、尽量使用...
  • WKWebView的使用

    千次阅读 2015-05-05 20:54:35
    iOS8 以前我们是通过UIWebView加载网页的,但是通过UIWebView网页加载一直存在不少问题:加载速度慢,占用内存多,优化困难等;iOS8以后,苹果推出了WebKit新框架,可以通过新的UI组件WKWebView来替代原来的...
  • iOS WKWebView UIWebView

    2018-01-08 08:52:45
    这个自iOS2开始使用的网页加载器一直是开发的心病:加载速度慢,占用内存多,优化困难。如果加载网页多,还可能因为过量占用内存而给系统kill掉。各种优化的方法效果也不那么明显(点击查看常用优化方法)。 iOS8...
  • WKWebView替换UIWebView

    2016-03-23 11:05:19
    这个自iOS2开始使用的网页加载器一直是开发的心病:加载速度慢,占用内存多,优化困难。如果加载网页多,还可能因为过量占用内存而给系统kill掉。各种优化的方法效果也不那么明显(点击查看常用优化方法)。 iOS8...
  • iOS WKWebView简单使用

    2019-11-24 01:03:39
    文章目录WKWebView简单介绍使用方法准备加载网页加载文件界面返回到app代理协议 ...WKWebView解决了UIWebView加载速度慢,占用内存多,优化困难等问题,可以说,WKWebView是目前App 内部加载网页的最佳选择。 WKWeb...
  • 而这个自iOS2.0开始使用的Web容器一直是开发的心病:加载速度慢,占用内存多,优化困难。如果加载网页多,还可能因为过量占用内存而给系统kill掉。各种优化的方法效果也不那么明显iOS8 以后,苹果推出了新框架 ...
  • 这个自iOS2开始使用的网页加载器一直是开发的心病:加载速度慢,占用内存多,优化困难。如果加载网页多,还可能因为过量占用内存而给系统kill掉。各种优化的方法效果也不那么明显(点击查看常用优化方法)。 iOS8...
  • IOS WKWebView

    2019-07-14 12:29:08
    文章目录简介属性:WKWebView常用方法介绍基本使用-加载网页准备工作网页控制加载本地文件WKNavigationDelegate 简介 通用型很强,程序员只需要能识别网页端,相应的就能开发对应的ios和androw版本,只需要把网页...
  • UIWebView & WKWebView

    2018-05-10 09:48:37
    1. UIWebView VS WKWebView稳定性:UIWebView较多的WebCore、JavaScriptCore Crash,以及系统性的内存泄露导致OOM,对整个App的稳定性都是极大的隐患。反观WKWebView,基于独立进程,不会...加载速度:WKWebView通过J...
  • 提供了替换UIWebView的组件, WKWebView解决了UIWebView加载速度慢,占用内存多,优化困难等问题,可以说WKWebView是目前App内部加载网页的最佳选择。 目录 1.JS 与 OC 交互 2.OC 向 JS 传递值 1.JS 与 OC ...
  • 比如加载速度慢,内存泄露等问题。WKWebView是在iOS 8 推出,前段时间正好把项目也适配到iOS 8 以上了,终于可以把项目中的UIWebView 替换成WKWebViewWKWebView的特点: 性能高,稳定性好,占用的内存比较小, ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 448
精华内容 179
关键字:

wkwebview加载速度慢