Navbar Objects Not Entering Safe Area with XCODE and WKWebView

  Kiến thức lập trình

I have a web app, and I am not an IOS developer of any sort. I simply want to display my webapp in an IOS application for the appstore. Luckily I’m aware of WKWebView. So with that in mind I have attempted to load my webapp into the webview and display it. However I’m encountering some weird issues. It seems the webview asset has some native conditions in which it interperets CSS and HTML in its own special way, as it is completely failing to render navbars where I want them to be. I am trying to ignore the safe area of the IOS setup. And I can’t make this work. I have tried multiple times to no success. When I ignore the safe areas, the majority of the app ignores them, apart from some navbar styled elements…. I thought this was weird so I changed the app to w3schools.com and noticed the same glitch. safe area still blocks the navbar… How can I make it not do this!!

I have my
webView.topAnchor.constraint(equalTo: view.topAnchor) and this allows the body to go all the way to the top of the physical screen as shown below.

But notice the red box I have added to highlight the way in which the navbar of any website cant also go up there….. it also seems to similarly do some funky stuff with any fixed elements at the bottom of the app. But that might be resolved by fixing this top issue.

I really need a fix for this. Any help at all would be appreciated. My full ViewController code is present below aswell for help.

Many Thanks.

My Entire ViewController Code

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {
    var webView: WKWebView!
    var connectingLabel: UILabel!
    var errorLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
       
        // Create the WKWebView instance
        webView = WKWebView()
        webView.translatesAutoresizingMaskIntoConstraints = false
        webView.navigationDelegate = self
        view.addSubview(webView)
        
        
        // Create the "Connecting" UILabel instance
        connectingLabel = UILabel()
        connectingLabel.text = "Connecting"
        connectingLabel.textAlignment = .center
        connectingLabel.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(connectingLabel)
        
        // Create the "Service Offline" UILabel instance
        errorLabel = UILabel()
        errorLabel.text = "Service Offline"
        errorLabel.textAlignment = .center
        errorLabel.translatesAutoresizingMaskIntoConstraints = false
        errorLabel.isHidden = true
        view.addSubview(errorLabel)
        
        // Set up auto layout constraints for WKWebView to fill the entire view, including areas under status bar and home indicator
        NSLayoutConstraint.activate([
            webView.topAnchor.constraint(equalTo: view.topAnchor),
            webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            webView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
        ])
        
        // Set up auto layout constraints for "Connecting" UILabel
        NSLayoutConstraint.activate([
            connectingLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            connectingLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])
        
        // Set up auto layout constraints for "Service Offline" UILabel
        NSLayoutConstraint.activate([
            errorLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            errorLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])
        
        // Disable double-tap to zoom (requires setting viewport settings)
        let viewportScript = """
        var meta = document.createElement('meta');
        meta.name = 'viewport';
        meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no';
        var head = document.getElementsByTagName('head')[0];
        head.appendChild(meta);
        """
        let userScript = WKUserScript(source: viewportScript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
        webView.configuration.userContentController.addUserScript(userScript)
        
        // Load the URL
        if let url = URL(string: "https://w3schools.com") {
            let request = URLRequest(url: url)
            loadCookies {
                self.webView.load(request)
            }
        }
        
        // Observe when the app is about to terminate or go into the background
        NotificationCenter.default.addObserver(self, selector: #selector(saveCookies), name: UIApplication.willTerminateNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(saveCookies), name: UIApplication.didEnterBackgroundNotification, object: nil)
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self, name: UIApplication.willTerminateNotification, object: nil)
        NotificationCenter.default.removeObserver(self, name: UIApplication.didEnterBackgroundNotification, object: nil)
    }
    
    // WKNavigationDelegate method to show "Connecting" label when content starts to load
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        connectingLabel.isHidden = false
        errorLabel.isHidden = true
    }
    
    // WKNavigationDelegate method to hide "Connecting" label when content finishes loading
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        connectingLabel.isHidden = true
    }
    
    // WKNavigationDelegate method to handle HTTP errors
    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        if let response = navigationResponse.response as? HTTPURLResponse, response.statusCode == 404 {
            errorLabel.isHidden = false
            connectingLabel.isHidden = true
            webView.isHidden = true
        }
        decisionHandler(.allow)
    }
    
    // Handle failure in loading
    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        connectingLabel.isHidden = true
        errorLabel.isHidden = false
    }
    
    @objc func saveCookies() {
        webView.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in
            let cookieDicts = cookies.map { cookie -> [String: Any] in
                return [
                    "name": cookie.name,
                    "value": cookie.value,
                    "domain": cookie.domain,
                    "path": cookie.path,
                    "expiresDate": cookie.expiresDate ?? Date.distantFuture,
                    "isSecure": cookie.isSecure
                ]
            }
            let userDefaults = UserDefaults.standard
            userDefaults.set(cookieDicts, forKey: "savedCookies")
            userDefaults.synchronize()
        }
    }
    
    func loadCookies(completion: @escaping () -> Void) {
        let userDefaults = UserDefaults.standard
        if let cookieDicts = userDefaults.array(forKey: "savedCookies") as? [[String: Any]] {
            let cookies = cookieDicts.compactMap { dict -> HTTPCookie? in
                return HTTPCookie(properties: [
                    .name: dict["name"]!,
                    .value: dict["value"]!,
                    .domain: dict["domain"]!,
                    .path: dict["path"]!,
                    .expires: dict["expiresDate"]!,
                    .secure: dict["isSecure"]!
                ])
            }
            let cookieStore = webView.configuration.websiteDataStore.httpCookieStore
            let dispatchGroup = DispatchGroup()
            for cookie in cookies {
                dispatchGroup.enter()
                cookieStore.setCookie(cookie) {
                    dispatchGroup.leave()
                }
            }
            dispatchGroup.notify(queue: .main) {
                completion()
            }
        } else {
            completion()
        }
    }
}

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT