7

I have set the WKWebView bottom constraint to super view but it won't display till super view 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 the 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 the issue here?

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

Bhavin Bhadani
  • 22,224
  • 10
  • 78
  • 108
  • Could you specify with background colors or whatever if the issue is in the added view or if it in the parent view? – Vasilis D. Aug 23 '19 at 13:32
  • What does the else case?? You create some constraints thad do nothing, I thing you should assign the constraints into variables and then add the variables to the view with self.view.addConstraint(constY) – Vasilis D. Aug 23 '19 at 13:38
  • @ΒασίληςΔ.else case too working fine just that bottom part doesn't seem over safe area. isActive means to add constraints in view. I think you should check doc regarding that – Bhavin Bhadani Aug 24 '19 at 03:43
  • Could the problem be in the container view instead of the web view? As others have suggested, you can try setting a red background for the container view and see if the view covers the whole screen or not. – Cristik Aug 26 '19 at 05:22
  • @Cristik Already tried that and check that constraint screenshot and first constraint, its already attached with superview bottom – Bhavin Bhadani Aug 26 '19 at 05:25

5 Answers5

6

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
Sahil Manchanda
  • 9,812
  • 4
  • 39
  • 89
1

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

niku
  • 472
  • 3
  • 12
-1

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
Naqeeb
  • 1,121
  • 8
  • 25
  • But ContainerView is already attached with `superview.bottom`. So, why we need this? – Bhavin Bhadani Aug 23 '19 at 10:05
  • i updated my answer. we have to just change in bottom anchor. you are setting constraint with containerview. set this to view which is root element – Naqeeb Aug 23 '19 at 10:18
  • replace containerView.addSubview(wv) with view.addSubview(wv). beacuse container view is like safe area – Naqeeb Aug 23 '19 at 10:25
  • bro its not like safe area. Please check screenshot for constraints. Container view is attached with superview's bottom. – Bhavin Bhadani Aug 23 '19 at 10:25
  • check out the difference of containerview and view it will help to solve this out – Naqeeb Aug 23 '19 at 10:27
-1

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.

Damien
  • 3,322
  • 3
  • 19
  • 29
  • That's not possible. If we give constraint to container view bottom with safe area bottom then whatever it is (storyboard or coding), it makes no difference. – Bhavin Bhadani Aug 25 '19 at 04:37
-1

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