How to avoid a blink when UIWebView loads HTML - ios

I have a native iOS app that contains a tab bar. The view controller for each tab contains a UIWebView. When the user switches between tabs, I load the HTML in the corresponding web view. The HTML is fully cached on a device. Here is how I feed the HTML to UIWebView:
[self.webView loadHTMLString:htmlString baseURL:baseUrl];
baseUrl is a file URL pointing to a directory where all assets are located.
This works great in online and offline modes, however it takes time for the UIWebView to parse and render the HTML. As a result, the user sees a brief blink of a white background when switching between tabs. I'd like to remove it, because the user is able to tell that the UI is not native (native UI renders instantly).
I was thinking about taking a screenshot of the UIWebView once it's done rendering the HTML and caching it in memory. The next time the user navigates to that web view, the app displays the screenshot while the UIWebView is rendering the HTML in the background. Finally, the app swaps the screen shot with the actual UIWebView and takes a new screenshot. This is similar to how Google Chrome app works.
Does anyone know a better solution to this problem?

Depends on how you present that web view. I'm not really sure from your description how you do it, but since you're talking about a blink of white background, I'm going to assume there is a situation where you have a web view with a loaded html and then you switch it to another html. The solution for that case would be:
create a second web view,
load the new html to this new web view,
when that web view finishes loading html (you can find out if you use UIWebViewDelegate) you can then quickly switch it with your old web view (meaning you finally add the new web view to the view hierarchy at THIS point, not when you created it).
This way you'll have an instant switch between old and new html, however user will be left waiting and it is your decision what to do with it. You could use UIActivityIndicatorView for example.

When webViewDidFinishLoad: gets called you can do any number of things, make the webview visible, remove something that you had on top of the webview etc...

Related

How does iOS 13 Safari link preview work?

In iOS 13 Safari, when you long press on a link, you see a preview of the linked page, along with some menu items. If you tap the preview, you navigate to that page.
Now, I see how to intervene in the long-press-and-preview process. This used to be peek-and-pop, but in iOS 13 that's deprecated and we're supposed to use func webView(_:contextMenuConfigurationForElement:) and so forth. Fine, but how would I imitate what Safari does?
The problem is that as my preview provider I have to supply a view controller. So I'm going to need a different view controller with a web view showing the linked page. Okay, I can do that. But then when the user taps the preview to dismiss it, I want to respond by loading the same linked page into my real web view.
But that's the problem. That loading takes time. In Safari, by contrast, when you tap the preview, boom, there's the same page already loaded. How do they do that? How would I do the same thing? How can I load the page into a different view controller, cache it, and communicate that cached page back to my real web view?

Different behaviour in WKWebview and Safari regarding CSS

There seem te be some subtle differences in the Implementation or configuration between WBWebView and Safari (and SFSafariViewController) that renders a part of the Website I want to display unusable.
Here is what I am trying to do:
Basically all that is needed is an "App" that just opens a specific website in fullscreen mode, so no chrome, URLs or additional navigaton buttons are present. The Website works fine on Safari on iOS (and every other (modern) browser on desktop or mobile) but the menu does not when embedded in the App.
All I did was creating a new single view Application in Xcode, drop in a WKWebView and have it load the URL. The part of the page not working is this menu component that is used throughout the site: http://tympanus.net/codrops/2013/04/19/responsive-multi-level-menu/ So basically the user has no way to navigate. While debugging the website it seems like when I push the menu button the menu does not expand like it should because the changed css classes dont get picked up correctly. If I manually toggle the css classes on the menu-element it gets displayed correctly. It makes me wonder if there are some additonal constraints related to WKWebView?
Can anyone tell me if there are any settings or configurations I can alter that allow the website in WKWebView to behave exactly the same as it would under Safari?
As far as I understand SFSafariViewController I always get the browser toolbar and navigational elements which I dont want to have in the app, so that is not an option- or is there a way to get rid of that?
Any help or pointers would be greatly appreciated :)

How to navigate back to a Page and avoid reloading webview?

I have a Windows Phone Store app (XAML) with a Page (MainPage.xaml) that has a webview that loads content and URLs. At certain point i have to navigate to a different windows phone page (Page2.xaml), once the data there is submitted i navigate back to MainPage.xaml, but the webview control always reloads the content and user has to reenter the data again.
Is there any way to make a snapshot of the webview and load it when Navigating back to MainPage.xaml?
I have tried the NavigationHelper, but in the onNavigatingFrom event from MainPage when i try to save the Frame.Content, its the Page2 the one being passed in the NavigationEventArgs.
Any ideas?
One way to do it is to never leave the page. To do this, create two grids. One for the webview and one for the other view. When the page loads, show the first grid and hide the second grid. When you want to show the second view hide the first grid and show the second.
I have used this method in several apps on the phone and windows store and you can simulate popups this way as well.

Strange UIWebView Bug/Behavior

We have a UIWebView in our app, displaying HTML data loaded from memory (not a file). We are experiencing some very strange bug/behavior. Some pages take very long time to render (1-2 minutes). We looked at the source of the pages, and it is indeed very busy with badly written CSS and HTML (not in our control). However, we noticed that if we set a webview to load a page, and then press the power button to shut the iPhone's screen, then immediately press the power button again, and go back to our app, the webview renders the page instantly.
Has anyone experienced this? Any ideas what's going on?
So, uhm, forgot to answer this. It ended up that some of our HTML data had images that were linking to internal organization URLs, which were not accessible outside. And since the web view did not ask the delegate whether it should load, we didn't know about those resources. Pressing the power button caused the connections to drop, which made it render the page.

Like Box Social Plugin iframe doesn't scroll in an UIWebView

I loaded the Like Box iframe code generated on Facebook into an UIWebView on my iPhone App. It works well, but when I scroll, it scrolls the UIWebView itself, and not the content inside the iframe. How can I block the UIWebView from scrolling (i.e the UIWebView takes the fullscreen frame) and allow the overflowed content of the iframe to scroll instead ?
ps : I tested a simple .html in MobileSafari.app and I have the same problem
You use two fingers in the like box instead of one. Then it scrolls.
You won't have much control over a plugin that is rendered as an iframe due to cross domain restrictions and they do not give many options to customize the appearance.
You could replace it with a Facebook like button. Then below it, you could add code that reads and displays the Fan Page feed using the graph api's page's feed connection (/pageId/feed). This would give you full control over the rendering and still gives the user the option to like your page. To improve performance of this solution you could use the Facebook real-time updates API to get notified when new updates get posted to the page and then you could pull those down and cache them.

Resources