Search code examples
iosswiftuiwebviewwebkitsfsafariviewcontroller

How to present SFSafariViewController in UIView


i have a custom UIView that has a button property, i want to add an action to it to open webview in-app. To do that i want to use SFSafariViewController. Here is how i am trying to achieve this.

import UIKit
import SafariServices

class CustomViewScreen: UIView, SFSafariViewControllerDelegate {

@IBAction func privacyNoteBtnAction(_ sender: UIButton) {
    if #available(iOS 9.0, *) {
        let urlString = "https://stackoverflow.com/"
        if let url = URL(string: urlString) {
            let vc = SFSafariViewController(url: url, entersReaderIfAvailable: true)
            vc.delegate = self
           UIApplication.shared.keyWindow?.rootViewController?.present(vc, animated: true, completion: nil)
        }
    } else {
        // Fallback on earlier versions
    }
}

func safariViewControllerDidFinish(_ controller: SFSafariViewController) { 
  controller .dismiss(animated: true, completion: nil) // also not able to trigger this method when i tap "Done"
}

I cant even propery use this way , since i am getting " whose view is not in the window hierarchy!" Also i am not able to call SFSafariViewControllerDelegate method to dismiss the view after tap "Done" button. Any idea to give action while i am in the UIView or any idea to connect this action to my main controller to use properly present method?


Solution

  • Do like this,

    @IBAction func privacyNoteBtnAction(_ sender: UIButton) {
       if #available(iOS 9.0, *) {
        let urlString = "https://stackoverflow.com/"
        if let url = URL(string: urlString) {
            let vc = SFSafariViewController(url: url, entersReaderIfAvailable: true)
            vc.delegate = self
    
           if var topController = UIApplication.shared.keyWindow?.rootViewController {
              while let presentedViewController = topController.presentedViewController {
                  topController = presentedViewController
              }
    
              topController.present(vc, animated: true, completion: nil)
           }
    
        }
    } else {
        // Fallback on earlier versions
    }
    }