ios SFSafariViewController:隐藏导航栏

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33813129/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:16:35  来源:igfitidea点击:

SFSafariViewController: Hide navigation bar

iosobjective-cswiftsfsafariviewcontroller

提问by Mike Purcell

I was able to get my app to automatically load a url via the SFSafariViewController per this post, and it works great, the only drawback is the navbar.

根据这篇文章,我能够让我的应用程序通过 SFSafariViewController 自动加载一个 url ,而且效果很好,唯一的缺点是导航栏。

The SFSafariViewController navbar is kind of useless when being used this way, as the url is read-only, and the 'done' link doesn't do anything but reload the page. As such, I would like to hide the navbar altogether.

SFSafariViewController 导航栏在以这种方式使用时是无用的,因为 url 是只读的,并且“完成”链接除了重新加载页面之外什么也不做。因此,我想完全隐藏导航栏。

Per the comments attached to accepted answer, it was suggested to set my root view controller to SFSafariViewController which I can't get working. The setup is simple as there is a single view controller with the code included in the aforementioned post.

根据附加到已接受答案的评论,建议将我的根视图控制器设置为 SFSafariViewController,但我无法正常工作。设置很简单,因为只有一个视图控制器,代码包含在上述帖子中。

How can I hide the navbar but still maintain the benefits of the SFSafariViewController? Or if I can't hide the navbar, at least hide the 'done' link?

如何隐藏导航栏但仍保持 SFSafariViewController 的优势?或者如果我不能隐藏导航栏,至少隐藏“完成”链接?

Code snippet:

代码片段:

import UIKit
import SafariServices

class ViewController: UIViewController
{
    private var urlString:String = "https://example.com"

    override func viewDidLoad()
    {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func viewDidAppear(animated: Bool)
    {

        super.viewDidAppear(animated)

        let svc = SFSafariViewController(URL: NSURL(string: self.urlString)!)

        self.presentViewController(svc, animated: true, completion: nil)

        self.navigationItem.rightBarButtonItem = nil
    }

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

----- Works. Navbar is "hidden" -----

----- 作品。导航栏是“隐藏的” -----

import UIKit
import SafariServices

class ViewController: UIViewController
{
    private var urlString:String = "https://example.com"

    override func viewDidLoad()
    {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        // This will remove the status (battery, time, etc) bar
        UIApplication.sharedApplication().statusBarHidden = true
    }

    override func viewDidAppear(animated: Bool) {

        super.viewDidAppear(animated)

        let svc = SFSafariViewController(URL: NSURL(string: self.urlString)!)

        // Kind of a hack, in that we really aren't removing the navbar
        //  Rather we are adjusting the starting point of the vpc object so it appears as the navbar is hidden
        self.presentViewController(svc, animated: true) {

            var frame = svc.view.frame
            let OffsetY: CGFloat = 42

            frame.origin = CGPoint(x: frame.origin.x, y: frame.origin.y - OffsetY)
            frame.size = CGSize(width: frame.size.width, height: frame.size.height + OffsetY)
            svc.view.frame = frame
        }
    }

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

    // For this to work be sure to set the following setting to OFF, in info.plist
    //  'View controller-based status bar appearance'
    override func prefersStatusBarHidden() -> Bool {
        return true
    }
}

采纳答案by Sahil Kapoor

Put this code in viewDidAppear:

把这段代码放进去 viewDidAppear:

let safariViewController = SFSafariViewController(URL: url)
presentViewController(safariViewController, animated: true) {
    var frame = safariViewController.view.frame
    let OffsetY: CGFloat  = 64
    frame.origin = CGPoint(x: frame.origin.x, y: frame.origin.y - OffsetY)
    frame.size = CGSize(width: frame.width, height: frame.height + OffsetY)
    safariViewController.view.frame = frame
}

To hide the status bar, set View controller-based status bar appearanceto YESin your info.plist file and insert this in your view controller.

要隐藏状态栏,View controller-based status bar appearanceYES在 info.plist 文件中设置为,并将其插入到视图控制器中。

override func prefersStatusBarHidden() -> Bool {
    return true
}

Warning: I will suggest you against using SFSafariViewController for full screen view because reloading is not possible(since reload button is in UINavigationBar). In case request fails, it will render the application useless. Rather go for full screen WKWebView with custom toolbar instead.

警告:我建议您不要使用 SFSafariViewController 进行全屏视图,因为无法重新加载(因为重新加载按钮在 UINavigationBar 中)。如果请求失败,它将使应用程序无用。而是选择带有自定义工具栏的全屏 WKWebView。

Update: To avoid hiding the reload button, just add a view/imageView over the done button in your SFSafariViewController and render button invisible or at least untappable.

更新:为了避免隐藏重新加载按钮,只需在 SFSafariViewController 中的完成按钮上添加一个视图/图像视图,并使按钮不可见或至少不可点击。

presentViewController(svc, animated: true) {
    let width: CGFloat = 66
    let x: CGFloat = self.view.frame.width - width

    // It can be any overlay. May be your logo image here inside an imageView.
    let overlay = UIView(frame: CGRect(x: x, y: 20, width: width, height: 44))
    overlay.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.5)
    svc.view.addSubview(overlay)
}

The problem with this approach is only that overlay stays on screen, but if you can find a nice image for it, you will be fine.

这种方法的问题仅在于叠加层停留在屏幕上,但如果您能为它找到漂亮的图像,那就没问题了。

回答by arango_86

Customising SafariViewController may not be a good idea.

自定义 SafariViewController 可能不是一个好主意。

The Apple Guidelines clearly says

苹果指南明确指出

SafariViewController must be used to visibly present information to users; the controller may not be hidden or obscured by other views or layers. Additionally, an app may not use SafariViewController to track users without their knowledge and consent.

SafariViewController 必须用于向用户直观地呈现信息;控制器可能不会被其他视图或图层隐藏或遮挡。此外,应用程序不得在用户不知情和同意的情况下使用 SafariViewController 跟踪用户。

Refer:-https://developer.apple.com/app-store/review/guidelines/

参考:- https://developer.apple.com/app-store/review/guidelines/

回答by brian.clear

import Foundation
import UIKit
import SafariServices

class MySafariFullScreenViewController: UIViewController  {

    override func viewDidLoad() {
        super.viewDidLoad()
        //WONT WORK read only you need to override it in this VC or in SFSafVC using extension - see bottom of this code
        //self.prefersStatusBarHidden = true

    }

    override func viewDidAppear(_ animated: Bool){
        let urlString = "https://......"
        //if a log screen - i think SFSafariViewController can handle this
        //let urlString = "https://<domain>login?redirect=https:<homescreen>"


        if let url: URL = URL(string: urlString) {
            let safariViewController = SFSafariViewController(url: url)
            present(safariViewController, animated: true) {

                var frame = safariViewController.view.frame
                //if status bar not hidden
                l//et OffsetY: CGFloat  = 64
                //if status bar hidden
                let OffsetY: CGFloat  = 44

                frame.origin = CGPoint(x: frame.origin.x, y: frame.origin.y - OffsetY)
                frame.size = CGSize(width: frame.width, height: frame.height + OffsetY)
                safariViewController.view.frame = frame


            }
        }else{
            //url error
        }



    }
    //this is for this vc - but for SFSafariVC you need override using extension
    override var prefersStatusBarHidden: Bool{
        get{
            return true
        }
    }

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

extension SFSafariViewController{
     override open var prefersStatusBarHidden: Bool{
        get{
            return true
        }
    }
}

回答by AlKozin

Just present it using presentViewController:animated:completion:

只需使用它呈现它 presentViewController:animated:completion:

https://stackoverflow.com/a/40460594/842655

https://stackoverflow.com/a/40460594/842655