这段时间在开发一个应用,其中大部分页面是加载Web页面,而UINavigationController原生框架的标题是根据页面加载结束,回调UIWebViewDelegate的时候获取的,示例代码如下。
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
self.navigationItem.title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
}
大部分Web页面跳转页面的时候都是重新加载URL,从而会触发UIWebViewDelegate回调。
问题来了,如果是Vue单页应用呢?因为Vue在加载时会一次性加载所有内容,而在该页面操作跳转都不需要重新加载URL,就不会触发UIWebViewDelegate回调。
可是如果我们还是需要在每次切换页面的时候获取Web信息时该怎么办呢,显然从UIWebViewDelegate回调中获取是不可能的了。在网上搜索了一下,基本的办法都是让Web开发修改代码或者增加Schema调用。
办法总是有的,毕竟Web页面是运行在原生上,如果原生都无法解决这问题,还怎么混下去。
现在说一下我的解决办法,用帧刷新回调!
因为我这里的需求就是获取Web页面的标题和加载情况等,所以我可以在每一帧的回调中获取Web页面的状态(这里就不要用定时器了,你确定每秒执行一次?看看CPU占用率!)
直接上代码吧
@interface WebViewController ()<UIWebViewDelegate>
@property(nonatomic, retain) UIWebView *webView;
@property(nonatomic, retain) CADisplayLink *displayLick;
@end
@implementation WebViewController
- (void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
if(_displayLick == nil){ // 初始化帧回调
_displayLick = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink)];
}
[_displayLick addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; // 因为viewWillAppear是在主线程里面执行的,所以是添加到主线程的RunLoop。
}
- (void) viewDidDisappear:(BOOL)animated
{
if(_displayLick != nil){ // 跳转到其他页面就把帧回调移除
[_displayLick removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
}
- (void) handleDisplayLink
{
self.navigationItem.title = [_webView stringByEvaluatingJavaScriptFromString:@"document.title"]; // 获取标题
_webView.isLoading; // 是否正在加载
}
@end