domid
domid

Reputation: 53

Getting an ios storyboard webView app to render in safe area

Probably a simple fix but I'm trying to get my simple ios storyboard app to render in the safe area on my iPhone 11.

It's currently taking up the entire view space and not using the safe area. I'm not confident whether I need to make any changes to the code or is it simply a setting in the storyboard view which is not on.

It's my first app. Thanks for your help.

import UIKit
import WebKit



class ViewController: UIViewController, WKUIDelegate {

    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let myURL = URL(string:"https://google.com")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)

        if #available(iOS 11.0, *) {
            webView.scrollView.contentInsetAdjustmentBehavior = .never;
        }

        webView.navigationDelegate = self
                webView.allowsBackForwardNavigationGestures = true

    }

    override func loadView() {

        let webConfiguration = WKWebViewConfiguration()
        webConfiguration.dataDetectorTypes = [.all]
        webView = WKWebView(frame: .zero, configuration: webConfiguration)


        
        webView.uiDelegate = self
        view = webView

    }

}

extension ViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction,
                 decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        guard
            let url = navigationAction.request.url else {
                decisionHandler(.cancel)
                return
        }

        let string = url.absoluteString
        if (string.contains("mailto:")) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
            decisionHandler(.cancel)

            return
        }
        if (string.contains("sms:")) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
            decisionHandler(.cancel)

            return
        }
        decisionHandler(.allow)
    }
    
    

    
}


class FullScreenWKWebView: WKWebView {
    override var safeAreaInsets: UIEdgeInsets {
        return UIEdgeInsets(top: 100, left: 0, bottom: 0, right: 0)
    }
}
  1. enter image description here

Upvotes: 1

Views: 1799

Answers (1)

Claudio
Claudio

Reputation: 5213

That's happening because you're setting the webView as the controller's view. I think the easiest approach is by setting the webView as a subView of the viewController main view. Start by moving the initialisation code from the loadView method to the viewDidLoad, add the webView as a subView and finally constrainer the webView anchors to the safeArea anchors.

import UIKit
import WebKit

class ViewController: UIViewController, WKUIDelegate {

    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let webConfiguration = WKWebViewConfiguration()
        webConfiguration.dataDetectorTypes = [.all]
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        
        webView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(webView)
        
        NSLayoutConstraint.activate([
            webView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
            webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            webView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
            webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
        ])
        
        let myURL = URL(string:"https://google.com")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)

        if #available(iOS 11.0, *) {
            webView.scrollView.contentInsetAdjustmentBehavior = .never;
        }

        webView.navigationDelegate = self
                webView.allowsBackForwardNavigationGestures = true

    }
}

extension ViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction,
                 decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        guard
            let url = navigationAction.request.url else {
                decisionHandler(.cancel)
                return
        }

        let string = url.absoluteString
        if (string.contains("mailto:")) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
            decisionHandler(.cancel)

            return
        }
        if (string.contains("sms:")) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
            decisionHandler(.cancel)

            return
        }
        decisionHandler(.allow)
    }
}

If the previous option is not valid, you can use your code and change the webView bounds using the viewSafeAreaInsetsDidChange method, making it aware of the safe area insets. Just add the following code:

override func viewSafeAreaInsetsDidChange() {
    super.viewSafeAreaInsetsDidChange()
    view.bounds = view.safeAreaLayoutGuide.layoutFrame
}

Upvotes: 5

Related Questions