これにより、SFSafariViewControllerを介してアプリにURLを自動的にロードさせることができました post 、それはうまく機能しますが、唯一の欠点はナビゲーションバーです。
SFSafariViewControllerナビゲーションバーは、URLが読み取り専用であり、「完了」リンクはページをリロードする以外に何もしないため、このように使用すると役に立たなくなります。そのため、ナビゲーションバーを完全に非表示にします。
承認された回答に添付されたコメントによると、ルートビューコントローラーをSFSafariViewControllerに設定することが提案されましたが、これは機能しません。前述の投稿に含まれているコードを備えた単一のViewControllerがあるため、セットアップは簡単です。
ナビゲーションバーを非表示にしながら、SFSafariViewControllerの利点を維持するにはどうすればよいですか?または、ナビゲーションバーを非表示にできない場合は、少なくとも「完了」リンクを非表示にしますか?
コードスニペット:
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.
}
}
-----動作します。 Navbarは「非表示」です-----
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
に設定し、これをViewControllerに挿入します。
override func prefersStatusBarHidden() -> Bool {
return true
}
警告:リロードが不可能なため(リロードボタンがUINavigationBarにあるため)、全画面表示にSFSafariViewControllerを使用しないことをお勧めします。リクエストが失敗した場合、アプリケーションは役に立たなくなります。代わりに、カスタムツールバーを備えたフルスクリーンの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)
}
このアプローチの問題は、オーバーレイが画面に表示されたままになることだけですが、そのための素敵な画像が見つかった場合は問題ありません。
SafariViewControllerをカスタマイズするのは良い考えではないかもしれません。
Appleガイドラインは明確に述べています
SafariViewControllerを使用して、ユーザーに情報を視覚的に提示する必要があります。コントローラは、他のビューまたはレイヤーによって非表示または隠されてはなりません。さらに、アプリは、ユーザーの知識と同意なしにSafariViewControllerを使用してユーザーを追跡することはできません。
参照:- https://developer.Apple.com/app-store/review/guidelines/
presentViewController:animated:completion:
を使用して提示するだけです
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
}
}
}