SFSafariViewController:隐藏导航栏
SFSafariViewController: Hide navigation bar
我能够让我的应用程序根据此 通过 SFSafariViewController 自动加载 url,并且效果很好,唯一的缺点是导航栏。
SFSafariViewController 导航栏在以这种方式使用时有点无用,因为 url 是只读的,而 'done' link 除了重新加载页。因此,我想完全隐藏导航栏。
根据已接受答案所附的评论,建议将我的根视图控制器设置为 SFSafariViewController,但我无法正常工作。设置很简单,因为只有一个视图控制器,其中包含上述 post.
中的代码
如何隐藏导航栏但仍保持 SFSafariViewController 的优势?或者如果我不能隐藏导航栏,至少隐藏 'done' link?
代码片段:
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.
}
}
----- 有效。导航栏是 "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
}
}
将此代码放入 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
}
要隐藏状态栏,请在您的 info.plist 文件中将 View controller-based status bar appearance
设置为 YES
并将其插入您的视图控制器。
override func prefersStatusBarHidden() -> Bool {
return true
}
警告:我建议您不要使用 SFSafariViewController 进行全屏查看,因为无法重新加载(因为重新加载按钮位于 UINavigationBar 中)。如果请求失败,它将使应用程序无用。
而是使用带有自定义工具栏的全屏 WKWebView。
更新:
为避免隐藏重新加载按钮,只需在 SFSafariViewController 中的完成按钮上添加一个 view/imageView 并使按钮不可见或至少不可点击。
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)
}
这种方法的问题只是叠加层停留在屏幕上,但如果你能为它找到一个漂亮的图像,你会没事的。
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
}
}
}
只需使用 presentViewController:animated:completion:
展示即可
自定义 SafariViewController 可能不是一个好主意。
Apple 指南明确指出
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.
参考:-https://developer.apple.com/app-store/review/guidelines/
我能够让我的应用程序根据此
SFSafariViewController 导航栏在以这种方式使用时有点无用,因为 url 是只读的,而 'done' link 除了重新加载页。因此,我想完全隐藏导航栏。
根据已接受答案所附的评论,建议将我的根视图控制器设置为 SFSafariViewController,但我无法正常工作。设置很简单,因为只有一个视图控制器,其中包含上述 post.
中的代码如何隐藏导航栏但仍保持 SFSafariViewController 的优势?或者如果我不能隐藏导航栏,至少隐藏 'done' link?
代码片段:
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.
}
}
----- 有效。导航栏是 "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
}
}
将此代码放入 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
}
要隐藏状态栏,请在您的 info.plist 文件中将 View controller-based status bar appearance
设置为 YES
并将其插入您的视图控制器。
override func prefersStatusBarHidden() -> Bool {
return true
}
警告:我建议您不要使用 SFSafariViewController 进行全屏查看,因为无法重新加载(因为重新加载按钮位于 UINavigationBar 中)。如果请求失败,它将使应用程序无用。 而是使用带有自定义工具栏的全屏 WKWebView。
更新: 为避免隐藏重新加载按钮,只需在 SFSafariViewController 中的完成按钮上添加一个 view/imageView 并使按钮不可见或至少不可点击。
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)
}
这种方法的问题只是叠加层停留在屏幕上,但如果你能为它找到一个漂亮的图像,你会没事的。
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
}
}
}
只需使用 presentViewController:animated:completion:
自定义 SafariViewController 可能不是一个好主意。
Apple 指南明确指出
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.
参考:-https://developer.apple.com/app-store/review/guidelines/