WKWebView bottom constraint set but won't work

2020-07-14 09:34发布

I have set WKWebView bottom constraint to superview but it won't display till superview instead displays content till safe area.

Here is the problem image that displays the bottom part doesn't fill properly.

enter image description here

And here is the hierarchy of view and constraints image

enter image description here

enter image description here

And code to setup WebView constraints with container view

    let wv = WKWebView(frame: containerView.frame, configuration: wvConfig)
    webView = wv
    containerView.addSubview(wv)

    // setup constraints
    wv.translatesAutoresizingMaskIntoConstraints = false
    if #available(iOS 11.0, *) {
        wv.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
        wv.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
        wv.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
        wv.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
    } else {
        NSLayoutConstraint(item: wv, attribute: .top, relatedBy: .equal, toItem: containerView, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: wv, attribute: .leading, relatedBy: .equal, toItem: containerView, attribute: .leading, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: wv, attribute: .trailing, relatedBy: .equal, toItem: containerView, attribute: .trailing, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: wv, attribute: .bottom, relatedBy: .equal, toItem: containerView, attribute: .bottom, multiplier: 1.0, constant: 0).isActive = true
    } 

So, Can anyone rectify issue here?

Some certain URL's it works, but not for all. Why?

5条回答
放我归山
2楼-- · 2020-07-14 10:18

Replace containerview with view in bottom constraint because root is view.

 view.addSubview(wv)

  wv.translatesAutoresizingMaskIntoConstraints = false
    if #available(iOS 11.0, *) {
        wv.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
        wv.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
        wv.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
        wv.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    }
    NSLayoutConstraint(item: wv, attribute: .top, relatedBy: .equal, toItem: containerView, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
            NSLayoutConstraint(item: wv, attribute: .leading, relatedBy: .equal, toItem: containerView, attribute: .leading, multiplier: 1.0, constant: 0).isActive = true
            NSLayoutConstraint(item: wv, attribute: .trailing, relatedBy: .equal, toItem: containerView, attribute: .trailing, multiplier: 1.0, constant: 0).isActive = true
            NSLayoutConstraint(item: wv, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1.0, constant: 0).isActive = true
查看更多
成全新的幸福
3楼-- · 2020-07-14 10:19

According to the given screenshot, bottom constraint is applied in to safe area.Add bottom constraint into SuperView. enter image description here

查看更多
Summer. ? 凉城
4楼-- · 2020-07-14 10:28

The following subclassed WKWebView might solve your problem:

class FullScreenWKWebView: WKWebView {

    override var safeAreaInsets: UIEdgeInsets {
        if #available(iOS 11.0, *) {
            let insects = super.safeAreaInsets
            return UIEdgeInsets(top: insects.top, left: insects.left, bottom: 0, right: insects.right)
        } else {
            return .zero
        }

    }
    override var alignmentRectInsets: UIEdgeInsets{
        let insects = super.alignmentRectInsets
        return UIEdgeInsets(top: insects.top-20, left: insects.left, bottom: 0, right: insects.right)
    }
}

The above snipped taken from

Full Code:

import UIKit
import WebKit
class FullScreenWKWebView: WKWebView {

    override var safeAreaInsets: UIEdgeInsets {
        if #available(iOS 11.0, *) {
            let insects = super.safeAreaInsets
            return UIEdgeInsets(top: insects.top, left: insects.left, bottom: 0, right: insects.right)
        } else {
            return .zero
        }

    }
    override var alignmentRectInsets: UIEdgeInsets{
        let insects = super.alignmentRectInsets
        return UIEdgeInsets(top: insects.top-20, left: insects.left, bottom: 0, right: insects.right)
    }
}
class ViewController: UIViewController {

    let contaienrView: UIView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    let webView: FullScreenWKWebView = {
        let v = FullScreenWKWebView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    func setupViews(){
        view.addSubview(contaienrView)
        contaienrView.addSubview(webView)
        let constrains = [
            contaienrView.topAnchor.constraint(equalTo: view.topAnchor),
            contaienrView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            contaienrView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            contaienrView.trailingAnchor.constraint(equalTo: view.trailingAnchor),

            webView.topAnchor.constraint(equalTo: contaienrView.topAnchor),
            webView.leadingAnchor.constraint(equalTo: contaienrView.leadingAnchor),
            webView.bottomAnchor.constraint(equalTo: contaienrView.bottomAnchor),
            webView.trailingAnchor.constraint(equalTo: contaienrView.trailingAnchor),
            ]
        NSLayoutConstraint.activate(constrains)
    }

    func loadRequest(){
        let url = URL(string: "https://afghan-gps.com/mobile")!
        let request = URLRequest(url: url)
        webView.load(request)
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
        loadRequest()
    }
}

output: 1. iOS version > 10 enter image description here

  1. iOS version <11 enter image description here
查看更多
小情绪 Triste *
5楼-- · 2020-07-14 10:32

your code looks fine, your problem might come from the containerView constraints.

If you are using storyboards, Xcode is probably setting constraints on safe area. In that case you should handle all the constraints programmatically.

查看更多
淡お忘
6楼-- · 2020-07-14 10:34

I am trying to reproduce the same issue, used your approach but didn't get any issue regarding bottom space.

class TestWebViewController: UIViewController{

@IBOutlet weak var containerView: UIView!

var wkWebView : WKWebView?

override func viewDidLoad() {
    super.viewDidLoad()
    addWKWebView()

    wkWebView?.load(URLRequest(url: URL(string: "https://www.google.com")!))
    wkWebView?.allowsBackForwardNavigationGestures = true

    // Do any additional setup after loading the view.
}

func addWKWebView() {
    let wvConfig = WKWebViewConfiguration.init()
    let wv = WKWebView(frame: containerView.frame, configuration: wvConfig)
    wkWebView = wv
    containerView.addSubview(wv)
    // setup constraints
    wv.translatesAutoresizingMaskIntoConstraints = false
    if #available(iOS 11.0, *) {
        wv.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
        wv.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
        wv.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
        wv.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
    } else {
        NSLayoutConstraint(item: wv, attribute: .top, relatedBy: .equal, toItem: containerView, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: wv, attribute: .leading, relatedBy: .equal, toItem: containerView, attribute: .leading, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: wv, attribute: .trailing, relatedBy: .equal, toItem: containerView, attribute: .trailing, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: wv, attribute: .bottom, relatedBy: .equal, toItem: containerView, attribute: .bottom, multiplier: 1.0, constant: 0).isActive = true
    }
}
}

View Hierarchy Constraints

Everything is working fine for me.

Output -

Output

Please let me know if I'm missing something.

UPDATE -

Issue is with scrollView of WKWebview.

In safe area WKScrollView.adjustedContentInset is set to {0, 0, 34, 0}.

To avoid this use

wv.scrollView.contentInsetAdjustmentBehavior = .never

Final output -

enter image description here

查看更多
登录 后发表回答