UIWebView white screen on every launch while preloading all tabs

戏子无情 提交于 2019-12-10 11:41:03

问题


Before I present my issue, I want to mention that I tried looking for solutions here and here.
I am creating a hybrid application which uses native UIWebView for rendering the responsive designed web application. Following is the issue description :
1. I have a UITabBarController.
2. Each of the tab has a UIWebView.
3. I have to preload all tabs.
4. I am showing a UIActivityIndicator till the content loads on the first tab.
5. White screen appears for about 8-10 seconds and then the content starts to appear.
I will be happy to see this time become 2-4 seconds.

Following is my implementation :

[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];
            }
        }
    }
}

In WebView controller's viewDidLoad I have :

[_tgWebView loadRequest:[NSURLRequest requestWithURL:homeURL]];  

I was looking forward to suppressesIncrementalRendering, but since I am preloading all tabs, this does not work. Since my app supports iOS 7+, thus WKWebView can't be applied here.
I also thought of increasing the launch image duration but learned that is won't be a good practice.
Can this be implemented using GCD?
Please bring out the pitfalls in my implementations so that my application makes better performance.


回答1:


First, have UIWebView on each tab hidden until it has finished loading, then show it. Underneath the UIWebView you can have some placeholder image to describe it loading. Then using the webViewDidFinishLoad delegate method show the web view when it has finished loading. This approach will be non blocking.

- (void)webViewDidFinishLoad:(UIWebView *)webview
{
    if (webview.isLoading)
        return;
    else
        webView.hidden = false;
}

Second, preload the first tab then load the subsequent tabs while displaying the first. You can do that by placing the following code in the first tabs viewDidLoad method:

// Preload the subsquent tabs
for (UIViewController *aVC in self.tabBarController.viewControllers)
    if ([aVC respondsToSelector:@selector(view)] && aVC != self)
        aVC.view;

This way, the additional tabs web views are loaded in the background in a non blocking manner. You could combine it with hiding the web views while loading in case the user navigates to the additional tabs before their pages load.

I tested this with three tabs and it worked nicely.

So the first view controller could look something like this: @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;
}

EDIT: Removed GDC as it was crashing when the views had WebViews




回答2:


This post made my day. I am now using NSNotificationCenter for this.




回答3:


It's hard to identify the where the problem is directly.

First, I suggest that you check your network connection by loading the page on a desktop machine on the same Wifi to see if it is your server that is too slow.

Also you can load your pages one by one instead of load all pages concurrently, since multiple HTTP request are not processed in a FIFO sequence, they may be processed out of order, and your page may need all resource to be loaded before displaying.

Do you control the web page your self? You can use safari inspector to inspect your web page to see where is the time spent, is it resource loading, javascript processing or rendering.



来源:https://stackoverflow.com/questions/28272576/uiwebview-white-screen-on-every-launch-while-preloading-all-tabs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!