简体   繁体   中英

How to create a sized WKWebView in Swift 3 / iOS 10

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..

屏幕截图

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
}

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.

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])  
        }

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)

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!))
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM