[英]Load ViewController's WebView before showing
我有一個帶有包含WebView的ViewController的應用程序。 因為WebView所顯示的網站很大,所以我想在啟動應用程序時加載ViewController,以便用戶只要使用WebView打開ViewController,它就會顯示已加載的頁面。
我嘗試覆蓋viewDidLoad(),loadView(),便捷的init()等。但是在實際顯示ViewController之前,我放置的所有內容似乎都沒有執行。
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
webViewVC = storyboard.instantiateViewController(withIdentifier: "WebViewController")
if let c = webViewVC.childViewControllers[0] as? WebViewController {
c.dDelegate = self
webViewVC.modalPresentationStyle = .popover
let popover = webViewVC.popoverPresentationController!
popover.delegate = self
popover.permittedArrowDirections = .up
webViewVC.loadView()
present(webViewVC, animated: true, completion: nil) //if I don't add this line, the ViewController doesn't seem to get created before showing
}
那么,在present()
之前我可以調用什么以執行一些ViewController的代碼? 我需要加載如下內容:
let wwConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: CGRect(x: 0, y: 0, width: self.view.layer.frame.width, height: self.view.layer.frame.height), configuration: wwConfiguration)
webView.navigationDelegate = self
webView.uiDelegate = self
let url = URL(string: . . .
您的問題尚不完全清楚,但是我假設您是通過另一個按鈕(例如,按下按鈕)從另一個視圖控制器中呈現Web視圖控制器的。 像這樣的東西
您需要做的是異步處理。
例…
WebViewController
class WebViewController: UIViewController {
@IBOutlet private weak var webView: WKWebView!
var didLoadWebView: (() -> Void)!
func loadWebView(completion: @escaping () -> Void) {
loadViewIfNeeded()
didLoadWebView = completion // Save this closure to be called when loaded
webView.navigationDelegate = self
webView.load(URLRequest(url: URL(string: "http://apple.com")!))
}
}
extension WebViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
didLoadWebView() // Call back to the presenting view controller
}
}
展示ViewController
class ViewController: UIViewController {
@IBAction func showWebView(_ sender: UIButton) {
let wvc = storyboard!.instantiateViewController(withIdentifier: "WebViewController") as! WebViewController
wvc.modalPresentationStyle = .popover
wvc.popoverPresentationController?.sourceView = sender
wvc.popoverPresentationController?.sourceRect = sender.bounds
wvc.loadWebView {
self.present(wvc, animated: true, completion: nil)
}
}
}
好吧,讓我們嘗試了解OP的要求。 他有一個viewController可以加載網頁,並且按照他的說法,加載時間太長,並且他不想讓用戶等待那么長時間。 同樣根據他關於啟動時間的問題,我假設視圖控制器是他在應用啟動后將顯示的第一個視圖控制器。
情況1:webViewVC是啟動后的第一個VC
在這里,我們可以獲得的最大“預取”時間是調用方法application:didFinishLaunchingWithOptions:時獲得的時間。 假設這里沒有執行太多的處理器繁重的過程,那么將沒有任何時間進行預取。 因此,唯一的選擇是顯示一個在UI中應該與launchScreen類似的屏幕,以便用戶可以在應用程序仍在加載時認為它。 (我個人要做的是將啟動屏幕設置為僅顯示應用程序主題顏色的屏幕,並使用應用程序圖標左右將我的第一個屏幕設置為啟動屏幕的動畫;這提供了更好的專業方法,同時也為我提供了足夠的時間讓事情滾動)
情況2:webViewVC不是第一個VC
在這里,該應用將在繼續使用webViewVC之前向用戶顯示另一個VC,這樣可以給我們一些時間來預取數據。 在這種情況下,我將在上一個VC的viewDidLoad時開始獲取數據。 顯然,在執行某些操作之后,將調用webViewVC,這樣您就可以花點時間完成該操作(可能由用戶執行)。
使用DUMMY啟動屏幕加載VC
let webViewVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "WebViewController") as! WebViewController
let wwConfiguration = WKWebViewConfiguration()
let webView = WKWebView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height), configuration: wwConfiguration)
webView.navigationDelegate = webViewVC
webView.uiDelegate = webViewVC
let url = URL(string:"https://www.codemag.com/article/1405051/Understanding-and-Using-iBeacons")
webView.load(URLRequest(url: url!))
webViewVC.webView = webView
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) {
webViewVC.modalPresentationStyle = .popover
let popover = webViewVC.popoverPresentationController!
//popover.delegate = webViewVC
popover.permittedArrowDirections = .up
webViewVC.loadView()
self.present(webViewVC, animated: true, completion: nil)
webViewVC.showWebView()
}
該代碼實例化了webviewVC並開始加載數據,但僅在10秒鍾的預取時間后顯示。 showWebView()方法很簡單
func showWebView() {
view.addSubview(webView)
}
DispatchQueue.main.asyncAfter()
中的所有代碼更改為按鈕動作來將頁面加載為動作(例如,單擊按鈕時)。 一旦潛在客戶完成,您就可以在這里使用@AshleyMills代碼啟用按鈕。 干杯!
嘗試使用webViewVC.loadViewIfNeeded()
而不是webViewVC.loadView()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.