SFSafariViewController:隐藏导航栏
Posted
技术标签:
【中文标题】SFSafariViewController:隐藏导航栏【英文标题】:SFSafariViewController: Hide navigation bar 【发布时间】:2015-11-19 19:51:39 【问题描述】:我能够让我的应用程序通过 SFSafariViewController 根据 post 自动加载一个 url,而且效果很好,唯一的缺点是导航栏。
SFSafariViewController 导航栏在以这种方式使用时有点没用,因为 url 是只读的,并且“完成”链接除了重新加载页面之外什么都不做。因此,我想完全隐藏导航栏。
根据附加到已接受答案的 cmets,建议将我的根视图控制器设置为我无法工作的 SFSafariViewController。设置很简单,因为只有一个视图控制器,代码包含在上述帖子中。
如何隐藏导航栏但仍保持 SFSafariViewController 的优点?或者,如果我无法隐藏导航栏,至少隐藏“完成”链接?
代码sn-p:
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.
----- 有效。导航栏是“隐藏的” -----
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
【问题讨论】:
你能继承SFSafariViewController
并隐藏viewWillAppear:
上的导航栏吗?
我可以试试...我是 ios dev 的新手,所以任何代码 sn-ps 都会有帮助。
您可以尝试类似:self.navigationItem.rightBarButtonItem = nil
@CraigOtis:似乎不起作用,因为“完成”链接仍在呈现。我宁愿删除整个导航栏。但是,我想知道在 SFSafariViewController 的上下文中,navbar 是否指的是底部导航菜单。
不应该——底部菜单是toolbar
,如果您需要全屏解决方案,我认为更好的方法可能是切换到UIWebView
。
【参考方案1】:
将此代码放入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)
这种方法的问题只是叠加层停留在屏幕上,但如果你能找到一个漂亮的图像,你会没事的。
【讨论】:
Ic,因此建议将 svc 对象向上移动 64 个像素,从而“隐藏”导航栏。有用。剩下的唯一问题是prefersStatusBarHidden
覆盖似乎不起作用,因为状态栏仍在呈现。
让prefersStatusBarHidden
工作。谢谢。但是 SFSafariViewController 不是提供更多优势,例如 cookie 处理和更好的 javascript 渲染(通过 nitro)吗? cookie 处理对我们来说非常重要,因为我们现在可以通过移动设备进行 FB 分享。
是的,确实如此。可能苹果以后会在SafariServices上提供更多的选择。
多么可怕的黑客攻击
"为避免隐藏重新加载按钮,只需在 SFSafariViewController 中的完成按钮上添加一个 view/imageView 并渲染按钮不可见或至少不可点击。" - 由于 SafariViewController 上的 Apple 文档,我不建议这样做。来自 Apple 文档:重要根据 App Store Review Guidelines,此视图控制器必须用于向用户展示信息;控制器不能被其他视图或层隐藏或遮挡。此外,应用不得在未经用户知情和同意的情况下使用 SFSafariViewController 跟踪用户。【参考方案2】:
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
【讨论】:
【参考方案3】:自定义 SafariViewController 可能不是一个好主意。
Apple 指南明确说明
SafariViewController 必须用于向用户展示信息;控制器不能被其他视图或层隐藏或遮挡。此外,应用不得在未经用户知情和同意的情况下使用 SafariViewController 跟踪用户。
参考:-https://developer.apple.com/app-store/review/guidelines/
【讨论】:
【参考方案4】:只需使用presentViewController:animated:completion:
展示它
https://***.com/a/40460594/842655
【讨论】:
以上是关于SFSafariViewController:隐藏导航栏的主要内容,如果未能解决你的问题,请参考以下文章
是否有任何解决方法可以避免 SFSafariViewController 隐藏固定位置的标题?
iOS 9 - 在通过 SFSafariViewController 加载的网页底部隐藏工具栏
带有主页按钮的sfsafariviewcontroller覆盖不起作用
使用 SFSafariViewController 下载文档