I have a UIViewController
with UIWebViewDelegate
. I found that I can present it just fine but not push it. If I try to push it the target view controller loads and executes any variables set but does not fire viewDidLoad()
and instead just returns to my calling menu view controller without error.
I set a breakpoint on the first var declaration after the class and stepped through the code. When it got to webView init it flashed up the home (not target) view controller in the simulator and then continued though the var declarations before returning back to my home view controller.
Here is my menu code
works:
let myWebViewController = MyWebViewController()
myWebViewController.urlString = "myUrl"
present(myWebViewController, animated: true, completion: nil)
does not work
let myWebViewController = MyWebViewController()
myWebViewController.urlString = "myUrl"
let navController = (UIApplication.shared.delegate as! AppDelegate).navController
navController!.pushViewController(myWebViewController, animated: true)
Here is my redacted target view controller code. The URL to load is set in the menu.
import UIKit
class MyWebViewController: UIViewController, UIWebViewDelegate {
var urlString: String = "invalid url"
var url: URL {
return URL(string: urlString)!
}
var urlRequest: URLRequest {
var urlRequest = URLRequest(url: url)
return urlRequest
}
let webView: UIWebView = {
let view = UIWebView()
view.backgroundColor = .white
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
// declare various buttons and stack views
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
contentStackView.addArrangedSubview(webView)
mainStackView.addArrangedSubview(contentStackView)
view.addSubview(mainStackView)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
webView.loadRequest(urlRequest as URLRequest)
}
The problem has nothing to do with the web view, the web view controller, or anything else except where you're pushing the view controller. You are saying:
let navController = (UIApplication.shared.delegate as! AppDelegate).navController
navController!.pushViewController(myWebViewController, animated: true)
That is highly unusual. The usual thing is that we are inside a navigation interface already, and we push onto its stack:
let navController = self.navigationController
navController!.pushViewController(myWebViewController, animated: true)
But you are not saying that. Why not? I'm guessing it's because self
does not have a navigationController
. So you are successfully pushing onto the navigation controller, all right, but you are not seeing anything happening because the navigation controller is behind the scenes — the self
view controller's view is blocking it or has replaced it.
And that explains why you never detect the url loading. Your call to webView.loadRequest
is in viewWillAppear
. But this view will not appear; it is behind the scenes. viewWillAppear
is never called. Similarly viewDidLoad
is not called, because this view is not going to load; the navigation controller is not occupying the interface — self
is.