Because we make wkWebView as the root view, the button I added on my layout doesn't appear on screen. Then I tried to add wkWebView as a subview of the root view, but the app crashes. Then I found about UIBarButtonItem, but it seems that you could only create 2 buttons.
I need to add 5 buttons anywhere on the screen. Is there a workaround for this? I'm a newbie on ios development and I'm not that good at using the interface builder.
After trying @Matic Oblak's code and placing it on loadView() where I do my wkwebview initialization, I'm getting an error saying "Warning: Attempt to present SomeViewController on WebViewController whose view is not in the window hierarchy!
This is my current code.
override func loadView() {
// let contentController: WKUserContentController = WKUserContentController()
// let config: WKWebViewConfiguration = WKWebViewConfiguration()
//
// contentController.add(self, name: "callbackHandler")
// config.userContentController = contentController
//
// webView = WKWebView(
// frame: UIScreen.main.bounds,
// configuration: config
// )
//webView.navigationDelegate = self
//webView.translatesAutoresizingMaskIntoConstraints = false
//webView.scrollView.isScrollEnabled = false
//view = webView
if let webViewContainer = webviewContainer {
// Initialize:
let contentController: WKUserContentController = WKUserContentController()
let config: WKWebViewConfiguration = WKWebViewConfiguration()
contentController.add(self, name: "callbackHandler")
config.userContentController = contentController
let webView = WKWebView(frame: webViewContainer.bounds, configuration: WKWebViewConfiguration()) // Create a new web view
webView.translatesAutoresizingMaskIntoConstraints = false // This needs to be called due to manually adding constraints
webView.navigationDelegate = self
webView.translatesAutoresizingMaskIntoConstraints = false
webView.scrollView.isScrollEnabled = false
// Add as a subview:
webViewContainer.addSubview(webView)
// Add constraints to be the same as webViewContainer
webViewContainer.addConstraint(NSLayoutConstraint(item: webView, attribute: .leading, relatedBy: .equal, toItem: webViewContainer, attribute: .leading, multiplier: 1.0, constant: 0.0))
webViewContainer.addConstraint(NSLayoutConstraint(item: webView, attribute: .trailing, relatedBy: .equal, toItem: webViewContainer, attribute: .trailing, multiplier: 1.0, constant: 0.0))
webViewContainer.addConstraint(NSLayoutConstraint(item: webView, attribute: .top, relatedBy: .equal, toItem: webViewContainer, attribute: .top, multiplier: 1.0, constant: 0.0))
webViewContainer.addConstraint(NSLayoutConstraint(item: webView, attribute: .bottom, relatedBy: .equal, toItem: webViewContainer, attribute: .bottom, multiplier: 1.0, constant: 0.0))
// Assign web view for reference
self.webView = webView
}
}
override func viewDidLoad() {
if(someVar1.isEmpty && someVar2.isEmpty){
showSomeDialog()
}
}
The first commented lines on loadView() are my previous code for reference.
After placing @Matic Oblak's code on viewDidLoad(), I'm getting a black screen. Also, after placing the code that calls SomeViewController on viewDidAppear(), the error is gone but I'm still getting the black screen.
Actually
WKWebViewhas a bit of a nasty bug that it crashes when added in storyboard. But you can do that in code. What I usually do is create a view in storyboard just as a web view panel (usually full screen but not if you have some tool bars) then just add a new web view as a subview. I still use constraints to add the web view:So here
webViewContaineris dragged from storyboard as any view you want. It can even be the main view of the view controller if you want to.The rest should be explained in the comments.
So using this procedure you don't need to "hack" adding subviews on top of everything. You can add your button normally in your storyboard.
Note: The problem with using webViewContainer as main view is that web view will be added later than the rest of views so it may cover those you added in storyboard. You need to either send the web view to back or bring overlaying items to front. It is just adding
webViewContainer.sendSubviewToBack(webView)but I still prefer to use a separate view just for web view.