每次启动时 UIWebView 白屏,同时预加载所有选项卡
UIWebView white screen on every launch while preloading all tabs
在提出我的问题之前,我想提一下我曾尝试寻找解决方案 here and here。
我正在创建一个混合应用程序,它使用本机 UIWebView
来呈现响应式设计的 Web 应用程序。以下是问题描述:
1. 我有一个 UITabBarController
.
2. 每个选项卡都有一个UIWebView
.
3. 我必须预加载所有选项卡。
4. 我正在显示 UIActivityIndicator
,直到内容加载到第一个选项卡上。
5. 白屏出现约 8-10 秒,然后开始显示内容。
我会很高兴看到这个时间变成2-4秒。
以下是我的实现:
[self performSelectorOnMainThread:@selector(loadAllTabs) withObject:nil waitUntilDone:YES];
-(void) loadAllTabs
{
for(UIViewController * viewController in self.viewControllers){
if(![[NSUserDefaults standardUserDefaults]boolForKey:@"isSessionExpired"])
{
if((int)[self.viewControllers indexOfObject:viewController] != 4)
{
viewController.tabBarItem.tag = (int)[[self viewControllers] indexOfObject:viewController];
[viewController view];
}
}
}
}
在 WebView 控制器的 viewDidLoad
我有:
[_tgWebView loadRequest:[NSURLRequest requestWithURL:homeURL]];
我很期待 suppressesIncrementalRendering,但由于我预加载了所有选项卡,所以这不起作用。
由于我的应用程序支持iOS 7+,因此WKWebView无法在此处应用。
我还想到了 increasing 启动图像持续时间,但了解到这不是一个好的做法。
这可以使用 GCD 实现吗?
请指出我实现中的缺陷,以便我的应用程序具有更好的性能。
首先,隐藏每个选项卡上的 UIWebView,直到它完成加载,然后显示它。在 UIWebView 下,你可以有一些占位符图像来描述它的加载。然后使用 webViewDidFinishLoad 委托方法在完成加载时显示 Web 视图。这种方法将是非阻塞的。
- (void)webViewDidFinishLoad:(UIWebView *)webview
{
if (webview.isLoading)
return;
else
webView.hidden = false;
}
其次,预加载第一个选项卡,然后在显示第一个选项卡的同时加载后续选项卡。您可以通过将以下代码放在第一个选项卡的 viewDidLoad 方法中来做到这一点:
// Preload the subsquent tabs
for (UIViewController *aVC in self.tabBarController.viewControllers)
if ([aVC respondsToSelector:@selector(view)] && aVC != self)
aVC.view;
这样,附加选项卡 Web 视图将以非阻塞方式在后台加载。您可以将它与加载时隐藏 Web 视图相结合,以防用户在加载页面之前导航到其他选项卡。
我用三个选项卡对此进行了测试,效果很好。
所以第一个视图控制器看起来像这样:
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Load the website
[self loadWebView];
// Preload the subsquent tabs
for (UIViewController *aVC in self.tabBarController.viewControllers)
if ([aVC respondsToSelector:@selector(view)] && aVC != self)
aVC.view;
}
-(void)loadWebView
{
// Create Request
NSURL *url = [NSURL URLWithString:@"http://anandTech.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// Load the page
[webView loadRequest:request];
}
- (void)webViewDidFinishLoad:(UIWebView *)webview
{
if (webview.isLoading)
return;
else
webView.hidden = false;
}
编辑:
删除了 GDC,因为当视图具有 WebViews
时它会崩溃
很难直接确定问题出在哪里。
首先,我建议您检查您的网络连接,方法是在同一 Wifi 上的台式机上加载该页面,看看是否是您的服务器速度太慢。
您也可以一个一个地加载您的页面,而不是同时加载所有页面,因为多个 HTTP 请求不是按 FIFO 顺序处理的,它们可能会被乱序处理,并且您的页面可能需要所有资源显示前加载。
你自己控制网页吗?您可以使用 safari inspector 检查您的网页,看看时间花在哪里,是资源加载、javascript 处理还是渲染。
post 成就了我的一天。我现在为此使用 NSNotificationCenter
。
在提出我的问题之前,我想提一下我曾尝试寻找解决方案 here and here。
我正在创建一个混合应用程序,它使用本机 UIWebView
来呈现响应式设计的 Web 应用程序。以下是问题描述:
1. 我有一个 UITabBarController
.
2. 每个选项卡都有一个UIWebView
.
3. 我必须预加载所有选项卡。
4. 我正在显示 UIActivityIndicator
,直到内容加载到第一个选项卡上。
5. 白屏出现约 8-10 秒,然后开始显示内容。
我会很高兴看到这个时间变成2-4秒。
以下是我的实现:
[self performSelectorOnMainThread:@selector(loadAllTabs) withObject:nil waitUntilDone:YES];
-(void) loadAllTabs
{
for(UIViewController * viewController in self.viewControllers){
if(![[NSUserDefaults standardUserDefaults]boolForKey:@"isSessionExpired"])
{
if((int)[self.viewControllers indexOfObject:viewController] != 4)
{
viewController.tabBarItem.tag = (int)[[self viewControllers] indexOfObject:viewController];
[viewController view];
}
}
}
}
在 WebView 控制器的 viewDidLoad
我有:
[_tgWebView loadRequest:[NSURLRequest requestWithURL:homeURL]];
我很期待 suppressesIncrementalRendering,但由于我预加载了所有选项卡,所以这不起作用。
由于我的应用程序支持iOS 7+,因此WKWebView无法在此处应用。
我还想到了 increasing 启动图像持续时间,但了解到这不是一个好的做法。
这可以使用 GCD 实现吗?
请指出我实现中的缺陷,以便我的应用程序具有更好的性能。
首先,隐藏每个选项卡上的 UIWebView,直到它完成加载,然后显示它。在 UIWebView 下,你可以有一些占位符图像来描述它的加载。然后使用 webViewDidFinishLoad 委托方法在完成加载时显示 Web 视图。这种方法将是非阻塞的。
- (void)webViewDidFinishLoad:(UIWebView *)webview
{
if (webview.isLoading)
return;
else
webView.hidden = false;
}
其次,预加载第一个选项卡,然后在显示第一个选项卡的同时加载后续选项卡。您可以通过将以下代码放在第一个选项卡的 viewDidLoad 方法中来做到这一点:
// Preload the subsquent tabs
for (UIViewController *aVC in self.tabBarController.viewControllers)
if ([aVC respondsToSelector:@selector(view)] && aVC != self)
aVC.view;
这样,附加选项卡 Web 视图将以非阻塞方式在后台加载。您可以将它与加载时隐藏 Web 视图相结合,以防用户在加载页面之前导航到其他选项卡。
我用三个选项卡对此进行了测试,效果很好。
所以第一个视图控制器看起来像这样: @implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Load the website
[self loadWebView];
// Preload the subsquent tabs
for (UIViewController *aVC in self.tabBarController.viewControllers)
if ([aVC respondsToSelector:@selector(view)] && aVC != self)
aVC.view;
}
-(void)loadWebView
{
// Create Request
NSURL *url = [NSURL URLWithString:@"http://anandTech.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// Load the page
[webView loadRequest:request];
}
- (void)webViewDidFinishLoad:(UIWebView *)webview
{
if (webview.isLoading)
return;
else
webView.hidden = false;
}
编辑: 删除了 GDC,因为当视图具有 WebViews
时它会崩溃很难直接确定问题出在哪里。
首先,我建议您检查您的网络连接,方法是在同一 Wifi 上的台式机上加载该页面,看看是否是您的服务器速度太慢。
您也可以一个一个地加载您的页面,而不是同时加载所有页面,因为多个 HTTP 请求不是按 FIFO 顺序处理的,它们可能会被乱序处理,并且您的页面可能需要所有资源显示前加载。
你自己控制网页吗?您可以使用 safari inspector 检查您的网页,看看时间花在哪里,是资源加载、javascript 处理还是渲染。
NSNotificationCenter
。