我有一个带有包含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: . . .
答案 0 :(得分:1)
您的问题尚不完全清楚,但是我假设您是通过另一个按钮(例如,按下按钮)从另一个视图控制器中呈现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)
}
}
}
答案 1 :(得分:0)
好的,让我们尝试了解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代码启用按钮。干杯!
答案 2 :(得分:-2)
尝试使用webViewVC.loadViewIfNeeded()
代替webViewVC.loadView()