2015-11-19 271 views
4

我能夠讓我的應用程序通過SFSafariViewController根據這個post自動加載一個url,它工作的很好,唯一的缺點是導航欄。SFSafariViewController:隱藏導航欄

當以這種方式使用SFSafariViewController導航欄時,這種方式毫無用處,因爲url是隻讀的,'done'鏈接除了重新加載頁面外沒有其他任何操作。因此,我想完全隱藏導航欄。

根據接受的答案附帶的評論,有人建議將我的根視圖控制器設置爲SFSafariViewController,我無法工作。設置很簡單,因爲有一個視圖控制器,其代碼包含在上述文章中。

如何隱藏導航欄,但仍然保持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. 
    } 
} 

-----作品。導航欄「隱藏」 -----

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 
    } 
} 
+0

你可以繼承'SFSafariViewController'並將導航欄隱藏在'viewWillAppear:'? – JAL

+1

我可以嘗試......我是helio newb在ios開發,所以任何代碼片段都會幫助。 –

+0

你可以嘗試像這樣:'self.navigationItem.rightBarButtonItem = nil' –

回答

6

把這個代碼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 appearanceYES並在此插入您的視圖控制器。

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

警告:我會建議你反對,因爲重裝是不可能的(因爲Reload按鈕是在UINavigationBar的)使用SFSafariViewController全屏視圖。如果請求失敗,它將使應用程序無效。 改爲使用自定義工具欄進行全屏WKWebView。

更新: 爲了避免隱藏Reload按鈕,只需在您的SFSafariViewController添加視圖/ ImageView的在完成按鈕和渲染按鈕無形的或至少untappable。

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) 
} 

這種方法的問題僅僅是覆蓋在畫面上停留,但如果你能找到它一個很好的形象,你將被罰款。

+0

Ic,所以建議將svc對象向上移動64個像素,從而「隱藏」導航欄。有用。剩下的唯一問題是'prefersStatusBarHidden'重寫似乎不起作用,因爲狀態欄仍在呈現。 –

+0

我更新了答案。 –

+0

有'prefersStatusBarHidden'工作。謝謝。但是,SFSafariViewController不能提供更多的優勢,如cookie處理和更好的JavaScript渲染(通過硝基)?我們現在可以通過手機支持FB股票,因此cookie處理對我們來說是巨大的。 –

0
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 
     } 
    } 
}