Reputation: 2019
I am attempting to add a WKWebView to my app that takes up about ~2/3 of the screen (leaving space at the bottom). Because there seems to be no way to add the WKWebView
to the storyboard, I added a regular UIView
. Then in my viewDidAppear
method I try and create a WKWebView
with the same bounds. Is this a sound approach?
My code looks like this:
@IBOutlet var conversationView: UIView!
override func viewDidAppear(_ animated: Bool) {
let webView = WKWebView(frame: conversationView.frame)
if let url = URL(string: "https://www.google.com") {
webView.load(URLRequest(url: url))
}
// conversationView = webView // <-- doesn't work :\
conversationView.addSubview(webView) // works!
}
Swaping the views outright doesn't work at all, so instead I add the web view as a subview of the temporary view I added to the storyboard. This at least lets me constrain it's position and size but still it feels very kludgy and like there must be a better way of doing this..
Upvotes: 6
Views: 6541
Reputation: 4905
You can try this hope it works
Note: Please set Frame according to your requirements.
import UIKit
import WebKit
class WKWebViewVC: UIViewController {
@IBOutlet weak var wkWebviewBGView: UIView!
var wkWebview: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
wkWebview = WKWebView(frame: wkWebviewBGView.bounds, configuration: WKWebViewConfiguration())
wkWebview.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.wkWebviewBGView.addSubview(wkWebview)
let url = URL(string: "https://www.google.com")
wkWebview.load(URLRequest(url: url!))
}
}
Upvotes: 0
Reputation: 3323
None of the other answers worked for me. The answer by Samip Shah is along the right track but the constraints are not quite correct. The important thing to remember is to set translatesAutoresizingMaskIntoConstraints to false.
So, here's my solution. In the storyboard create a UIView with the constraints and layout you want for the WKWebView. In your view controller add the code:
@IBOutlet var contentView: UIView!
var wkWebView:WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
wkWebView = WKWebView(frame:contentView.frame)
contentView.addSubview(wkWebView)
constrainView(view: wkWebView, toView: contentView)
let request = URLRequest(url: /* your url here */)
wkWebView.load(request)
}
The code for constraining the view. You might add this to a utilities class if you want to use it more than one view controller.
func constrainView(view:UIView, toView contentView:UIView) {
view.translatesAutoresizingMaskIntoConstraints = false
view.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
view.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
view.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
}
Upvotes: 8
Reputation: 874
If you want to give constraints that size and postion the webview with respect to its container view, you can do like this.
@IBOutlet weak var wkWebBackgroundView: UIView!
var wkWebView:WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
setUpView()
}
func setUpView(){
self.wkWebView = WKWebView(frame: CGRect.zero)
self.wkWebBackgroundView.addSubview(wkWebView)
let height = NSLayoutConstraint(item: wkWebView, attribute: .height, relatedBy: .equal, toItem: wkWebBackgroundView, attribute: .height, multiplier: 1, constant: 0)
let width = NSLayoutConstraint(item: wkWebView, attribute: .width, relatedBy: .equal, toItem: wkWebBackgroundView, attribute: .width, multiplier: 1, constant: 0)
let top = NSLayoutConstraint(item: wkWebView, attribute: .top, relatedBy: .equal, toItem: wkWebBackgroundView, attribute: .top, multiplier: 1, constant: 0)
let leading = NSLayoutConstraint(item: wkWebView, attribute: .leading, relatedBy: .equal, toItem: wkWebBackgroundView, attribute: .leading, multiplier: 1, constant: 0)
view.addConstraints([leading, top, height, width])
}
Upvotes: 1
Reputation: 2222
You can just size the webview frame as desired without using a different view.
let webView = WKWebView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height * 0.66).integral)
view.addSubview(webView)
However, if you need the view in the storyboard to line up other subview constraints then your method works fine.
Edit: Just saw your added screenshot with comment stating the view is below a label:
let webView = WKWebView(frame: CGRect(x: label.frame.maxX + (whatever distance you want between label bottom and webView top), y: 0,
width: view.bounds.width, height: view.bounds.height * 0.66).integral)
view.addSubview(webView)
Upvotes: 0
Reputation: 535860
That's a very good approach; it is perfectly reasonable to have a "content view" whose job is merely to guide the web view into place, as it were. But it would be even better to add the web view plus constraints that size and position it.
Upvotes: 1