WKWebView appears halfway down the page if frame not set before load completes

Originator:wagner
Number:rdar://22855188 Date Originated:25-Sep-2015 02:04 PM
Status:Open Resolved:
Product:iOS SDK Product Version:9.0
Classification:Serious Bug Reproducible:Always
 
Summary:

I have a WKWebView which loads its contents offscreen. Once it loads, it is added to the view hierarchy.

However, I have found that if the WKWebView’s frame is set after the contents load (but while offscreen), once you add it to the view hierarchy it will adjust its contentOffset in an undesired way that makes it scroll 1.5 screens down the page. Setting the contentOffset in  the webView:didFinishNavigation: callback doesn’t help, as the undesired action happens some time after that.

Paste the following code in to a Playground (tested Xcode 7.0) to reproduce. 
==================

import UIKit
import WebKit
import XCPlayground

class WKViewController : UIViewController, WKNavigationDelegate
{
	var web            : WKWebView? = nil
	var loadNavigation : WKNavigation? = nil

	override func loadView()
	{
		super.loadView()

		view.backgroundColor = UIColor.orangeColor()

		web = WKWebView()
		web!.navigationDelegate = self
	}

	override func viewDidLoad()
	{
		let url     = "http://nshipster.com/mirrortype/"
		let nsURL   = NSURL(string:url)!
		let request = NSURLRequest(URL:nsURL)
		loadNavigation = web!.loadRequest(request)

		// NOTE: Uncomment this line to work-around
//		web!.frame = view.bounds
	}

	func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!)
	{
		print("finished")

		if navigation == loadNavigation
		{
			view.addSubview( webView )
			webView.frame = view.bounds
			// This line doesn't have any effect; CO gets set after this in some WKWebView magic.
			webView.scrollView.contentOffset = CGPoint.zero
		}
	}

	func webView(webView: WKWebView, didFailNavigation navigation: WKNavigation!, withError error: NSError)
	{
		print("failed")
	}
}

let vc = WKViewController()
XCPShowView( "", view: vc.view )

Comments

Same thing observed here, where I use WKWebViews in a UIPageController. Depending on when the page controller queries for UIViewControllers (it can do this in advance to make the page turns smooth), the WKWebView will scroll a bit down on the page (this is if view will not be onscreen when it is created) or correctly non-scrolled.

Easy to see by instead of swiping to turn pages you "click" the page indicators at the bottom; since these clicks will not trig pre-loading of the next view, no faulty "pre-scrolling" is done. However, swiping will now and then trig pre-scrolling, since swiping will mean that UIPageController sometimes asks for a UIController before it is actually visible.


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!