Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

set Webview in safe area of iphone X

I am new to Xcode and I don't know how to set webview in safe area of iPhone X. I have gone through couple of various answers, but they didn't help. The only thing I know about this app is, the view is set programmatically. Below is my ViewController.swift file.

import UIKit
import WebKit
import AVFoundation

class ViewController: UIViewController, WKScriptMessageHandler, WKNavigationDelegate, WKUIDelegate
{
    var webView       = WKWebView()
    var containerView = WKWebView() //Footer  Webview

    override func loadView()
    {
        super.loadView()
    }

    override func viewDidLoad()
    {
        super.viewDidLoad()

        let theConfiguration = WKWebViewConfiguration()

        //Bind Swift and Javascript interface through MessageHandler IOSJSObject
        theConfiguration.userContentController.add(self, name: "IOSJSObject")

        /* Webview intialization Start */
        webView = WKWebView(frame: CGRect(x: 0, y: 20, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height-65), configuration: theConfiguration)

        containerView = WKWebView(frame: CGRect(x: 0, y: UIScreen.main.bounds.height-45, width: UIScreen.main.bounds.width, height: 45), configuration: theConfiguration)
        /* Webview intialization End */


        /* Error Page Code Start */
        if(TestConnection.isConnectedToNetwork())
        {
            let url:URL = URL(string:"example.com")!

            let request :URLRequest = URLRequest(url:url)

            if let navController = self.navigationController
            {
                navController.popViewController(animated: true)
            }
            webView.load(request)
        }
        else
        {
            let path = Bundle.main.path(forResource: "error-connection", ofType: "html")
            let text = try? String(contentsOfFile:path!, encoding: String.Encoding.utf8)
            webView.loadHTMLString(text!, baseURL: nil)
        }

        /* Error Page Code End */

        self.view.backgroundColor = UIColor.white

        /* Container View Border Code Start*/
        let myColor : UIColor  = UIColor(red: 0, green: 0, blue: 0, alpha: 1)
        self.containerView.layer.borderColor = myColor.cgColor;
        self.containerView.layer.borderWidth = 0.5
        /* Container View Border Code End*/

        /* Container View Button Home Back Refresh Code Start*/
        let home = UIImage(named: "nptl-home.png")
        let back = UIImage(named: "nptl-back.png")
        //let refresh = UIImage(named: "nptl-refresh.png")


        let homeButton = UIButton()
        let backButton = UIButton()
        //let refreshButton = UIButton()

        homeButton.setImage(home, for: UIControlState())
        homeButton.setTitleColor(UIColor.blue, for: UIControlState())

        backButton.setImage(back, for: UIControlState())
        backButton.setTitleColor(UIColor.blue, for: UIControlState())

        //refreshButton.setImage(refresh, for: UIControlState())
        //refreshButton.setTitleColor(UIColor.blue, for: UIControlState())

        homeButton.frame = CGRect(x: (UIScreen.main.bounds.width/4)-50, y: 4, width: 37, height: 37)
        homeButton.addTarget(self, action: #selector(ViewController.home(_:)), for: UIControlEvents.touchUpInside)

        backButton.frame = CGRect(x: (UIScreen.main.bounds.width/1.33)+13, y: 4, width: 31, height: 37)
        backButton.addTarget(self, action: #selector(ViewController.goBack(_:)), for: UIControlEvents.touchUpInside)

        //refreshButton.frame = CGRect(x: UIScreen.main.bounds.width-60, y: 4, width: 48, height: 37)
        //refreshButton.addTarget(self, action: #selector(ViewController.doRefresh(_:)), for: UIControlEvents.touchUpInside)

        containerView.addSubview(homeButton)
        containerView.addSubview(backButton)
        //containerView.addSubview(refreshButton)

        /* Container View Button Home Back Refresh Code End*/

        self.view.addSubview(webView)
        self.view.addSubview(containerView)

        webView.navigationDelegate = self
        webView.uiDelegate  = self
        webView.scrollView.bounces = false   //No Bounce of Webview Screen From Top

        if(TestConnection.isConnectedToNetwork())
        {
            checkUpdate()
        }
    }


    func webView(_ webView: WKWebView,didFailProvisionalNavigation navigation: WKNavigation!,withError error: Error)
    {
        viewDidLoad()
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
    {
        if let messageBody:NSDictionary = message.body as? NSDictionary
        {
            print(" \(message.body)")

            let myActionName = messageBody["actionName"] as! String
            if myActionName == "shareApp"
            {
                let myShareAppSubject = messageBody["shareAppSubject"] as! String
                let myShareAppUrl = messageBody["shareAppURL"] as! String
                shareApp(myShareAppSubject,shareAppUrl:myShareAppUrl)
            }
            else if myActionName == "rateApp"
            {
                rateApp()
            }
            else if myActionName == "shareAppPage"
            {
                let myShareAppMessageSubject = messageBody["shareAppPageMessageSubject"] as! String
                let myShareAppMessageURL = messageBody["shareAppPageMessageURL"] as! String

                shareAppPage(myShareAppMessageSubject, shareAppPageURL: myShareAppMessageURL)
            }
            else if myActionName == "error"
            {
                viewDidLoad()
            }
            else if myActionName == "loadFromBaseUrl"
            {
                viewDidLoad()
            }
        }
    }

    func webView(_ webView: WKWebView,didStartProvisionalNavigation navigation: WKNavigation!)
    {
        UIApplication.shared.isNetworkActivityIndicatorVisible = true
    }

    /* Stop the network activity indicator when the loading finishes */
    func webView(_ webView: WKWebView,didFinish navigation: WKNavigation!)
    {
        UIApplication.shared.isNetworkActivityIndicatorVisible = false
    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: (@escaping (WKNavigationActionPolicy) -> Void))
    {
        if navigationAction.request.url?.scheme == "tel"
        {
            UIApplication.shared.openURL(navigationAction.request.url!)
            decisionHandler(.cancel)
            return
        }
        if navigationAction.request.url?.scheme == "mailto"
        {
            UIApplication.shared.openURL(navigationAction.request.url!)
            decisionHandler(.cancel)
            return
        }
        decisionHandler(.allow)
    }


    override func didReceiveMemoryWarning()
    {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // Start Of Custom bottomfooter


    @objc func doRefresh(_: AnyObject)
    {
        print("Refresh");

        webView.reload()
    }

    @objc func goBack(_: AnyObject)
    {
        if webView.canGoBack
        {
            webView.goBack()
        }
    }
    @objc func home(_: AnyObject)
    {
        //viewDidLoad()
        if(TestConnection.isConnectedToNetwork())
        {
            let url:URL = URL(string:"example.com")!

            let request :URLRequest = URLRequest(url:url)

            if let navController = self.navigationController
            {
                navController.popViewController(animated: true)
            }
            webView.load(request)

        }
        else
        {
            let path = Bundle.main.path(forResource: "error-connection", ofType: "html")
            let text = try? String(contentsOfFile:path!, encoding: String.Encoding.utf8)
            webView.loadHTMLString(text!, baseURL: nil)
        }
    }

    // End Of Custom bottomfooter


    // rate app
    func rateApp()
    {
        UIApplication.shared.openURL(URL(string: "https://itunes.apple.com/in/app/xyz/idxyz")!)
    }

    // share app
    func shareApp(_ shareAppText: String,shareAppUrl: String)
    {
        let firstActivityItem  = shareAppText
        let secondActivityItem = shareAppUrl

        print("printing firstActivityItem  \(firstActivityItem)")
        print("printing secondActivityItem  \(secondActivityItem)")


        let activityViewController : UIActivityViewController = UIActivityViewController(
            activityItems: [firstActivityItem, secondActivityItem], applicationActivities: nil)
        activityViewController.popoverPresentationController?.sourceView = self.view
        self.present(activityViewController, animated: true, completion: nil)
    }

    //share product page
    func shareAppPage(_ shareAppPageSubject: String, shareAppPageURL: String)
    {

        print("printing shareAppPageText  \(shareAppPageSubject)")

        let firstActivityItem = shareAppPageSubject


        let secondActivityItem : URL = URL(string: shareAppPageURL)!

        let activityViewController : UIActivityViewController = UIActivityViewController(
            activityItems: [firstActivityItem, secondActivityItem], applicationActivities: nil)
        activityViewController.popoverPresentationController?.sourceView = self.view
        self.present(activityViewController, animated: true, completion: nil)
    }

    //session handling
    func loadFromBaseUrl()
    {
        viewDidLoad()
    }

    func checkUpdate()
    {
        let nsObject : AnyObject! = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as AnyObject!

        let localVersion  = nsObject as! String

        let numberFromString = (localVersion as NSString).doubleValue

        print("ios App version "+localVersion)

        let UpdateUrl:NSURL = NSURL(string: "example.com?actionname=MobileAppAjaxHandler.getIOSMobileAppVersion")!

        let request:NSMutableURLRequest = NSMutableURLRequest(url:UpdateUrl as URL)

        let queue: OperationQueue = OperationQueue()

        // Sending Asynchronous request using NSURLConnection

        NSURLConnection.sendAsynchronousRequest(request as URLRequest, queue: queue, completionHandler:{(response:URLResponse?, responseData:Data?, error: Error?) -> Void in

            if error != nil
            {
                print(error.debugDescription)
            }
            else
            {
                //Converting data to String

                let responseStr = NSString(data: responseData!, encoding: String.Encoding.utf8.rawValue)

                print("response of remote Ios version  ========"+(responseStr! as String))

                let serverVersion = responseStr! as String

                let numfromstr = (serverVersion as NSString).doubleValue
                if numfromstr > numberFromString
                {
                    let updateBox = UIAlertController(title: "Update App", message: "App update is available on app store", preferredStyle: UIAlertControllerStyle.alert)
                    updateBox.addAction(UIAlertAction(title: "Update", style: .default, handler: { (action:UIAlertAction) in
                        UIApplication.shared.openURL(URL(string: "https://itunes.apple.com/in/app/xyz/idxyz")!)
                    }))
                    updateBox.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action:UIAlertAction) in

                    }))
                    self.present(updateBox, animated: true, completion: nil)
                }
            }
        })
    }

    override func viewWillAppear(_ animated: Bool)
    {
        print("inside view WillAppear for Portrait orientation");

        super.viewWillAppear(animated)
        let value = UIInterfaceOrientation.portrait.rawValue
        UIDevice.current.setValue(value, forKey: "orientation")
    }

    override var shouldAutorotate : Bool
    {
        print("shouldAutorotate return false");
        return false
    }

    override var supportedInterfaceOrientations : UIInterfaceOrientationMask
    {
        print("supportedInterfaceOrientations");
        return UIInterfaceOrientationMask.portrait
    }

    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void)
     {
     let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
     alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (_)-> Void in
     completionHandler()
     }))
     self.present(alert, animated: true, completion: nil)
     }

    func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void)
    {
        let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (_)-> Void in
            completionHandler(true)
        }))

        alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (_)-> Void in
            completionHandler(false)
        }))
        self.present(alert, animated: true, completion: nil)
    }
}

My Xcode version is 9.2 and this is the only file i have got. Any small help will be appreciated

like image 736
ashish pandey Avatar asked Nov 28 '18 09:11

ashish pandey


People also ask

What is the safeareainsets property on the iPhone X?

The safeAreaInsets property means that screen can be covered from all sides not only at the top and the bottom. When the iPhone X was presented it become clear why we would need the left and right insets. The iPhone X has the top and the bottom safe area insets in portrait orientation. Left, right and bottom insets in landscape orientation.

What are the New Safe Area properties in iOS 11?

In iOS 11 the UIViewController topLayoutGuide and the bottomLayoutGuide properties have been replaced by the new safe area properties in UIView: The safeAreaInsets property means that screen can be covered from all sides not only at the top and the bottom.

How to determine the safe area of the screen in Android?

Like iOS 11, Android P includes features to determine the safe area of the screen and work with the given insets. The new DisplayCutout class lets you find out the location and shape of the non-functional areas where content shouldn’t be displayed. To determine the existence and placement of the cutouts areas, use the getDisplayCutout () method.

What are additional safe area insets in UIView?

When you change the additional safe area insets or safe area insets are changed by the system, the appropriate methods in UIView and UIViewController are called Additional safe area insets also can be used to test how your app supports iPhone X.


1 Answers

Try to do autolayout using the layout anchors instead of frame to your custom WKWebView.

let containerViewHeight: CGFloat = 45

webView = WKWebView()//(frame: CGRect(x:0, y: 0, width:screenWidth, height:screenHeight))
view.addSubview(webView)

webView.translatesAutoresizingMaskIntoConstraints = false
webView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0).isActive = true
webView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0.0).isActive = true
webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0.0).isActive = true
webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -containerViewHeight).isActive = true

containerView = WKWebView()//(frame: CGRect(x:0, y: 0, width:screenWidth, height:screenHeight))
view.addSubview(containerView)

containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0).isActive = true
containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0.0).isActive = true
containerView.topAnchor.constraint(equalTo: webView.bottomAnchor, constant: 0.0).isActive = true
containerView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0.0).isActive = true

For the glance of safeArea region I've added the below image.

enter image description here

like image 77
Sateesh Yemireddi Avatar answered Oct 16 '22 12:10

Sateesh Yemireddi