2015-11-09 50 views
1

我試圖在UINavigationBar內顯示一個進度條,如下所述:Showing a UIProgressView inside or on top of a UINavigationController's UINavigationBar使用隱藏條更新ProgressView的限制條形圖

自定義的UINavigationController類看起來像這樣在斯威夫特完成時:

class NavigationControllerWithProgress: UINavigationController { 

    var progressView: UIProgressView! 
    var progressBottomConstraint: NSLayoutConstraint! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     hidesBarsOnSwipe = true 
     hidesBarsWhenVerticallyCompact = true 

     // adding ProgressView to UINavigationController to allow it to be placed inside the UINavigationBar 
     // see: https://stackoverflow.com/questions/19211999/showing-a-uiprogressview-inside-or-on-top-of-a-uinavigationcontrollers-uinaviga 
     progressView = UIProgressView(progressViewStyle: UIProgressViewStyle.Bar) 
     view.addSubview(progressView) 

     progressView.translatesAutoresizingMaskIntoConstraints = false 
     progressView.setProgress(0.5, animated: false) 

     progressBottomConstraint = NSLayoutConstraint(item: progressView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self.navigationBar, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: -0.5) 
     view.addConstraint(progressBottomConstraint) 

     var constraint: NSLayoutConstraint 

     constraint = NSLayoutConstraint(item: progressView, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Left, multiplier: 1, constant: 0) 
     view.addConstraint(constraint) 

     constraint = NSLayoutConstraint(item: progressView, attribute: NSLayoutAttribute.Right, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Right, multiplier: 1, constant: 0) 
     view.addConstraint(constraint) 
    } 
} 

的問題:一旦UINavigationBar的是OnSwipe/WhenVerticallyCompact約束停止工作,即ProgressView下錯位自動隱藏狀態欄。

我試圖在updateViewConstraints()和/或viewWillLayoutSubviews()中更新它,這是我目前看到的唯一方法。

作爲常數已用於相對於所述UINavigationBar的分離器中的位置(參見鏈接SO線程),我試圖此測試updateViewContraints()對於這種情況:

override func updateViewConstraints() { 
    super.updateViewConstraints() 

    view.removeConstraint(progressBottomConstraint) 
    progressBottomConstraint = NSLayoutConstraint(item: progressView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.navigationBar, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 30) 
    view.addConstraint(progressBottomConstraint) 
} 

注意常數設置爲30爲這個測試。

從做這個,我可以看到,約束沒有發揮好與UINavigationBar的自動隱藏:隱藏在/顯示導航欄與旋轉(在垂直緊湊)或輕掃酒吧是

  • 在肖像當UINavigationBar的下30像素,但在最高層
  • 當UINavigationBar的是隱藏在景觀
  • 不可見的(被覆蓋)時顯示在風景UINavigationBar的

有什麼建議嗎?

回答

0

雖然可以通過代碼自動佈局約束這樣做,使用組件,這裏SnapKit,使它變得更加簡單:

override func viewDidLoad() { 
    super.viewDidLoad() 

    [...] 
    progressView.snp_makeConstraints { (make) -> Void in 
     progressViewTopConstraint = make.top.equalTo(snp_topLayoutGuideBottom).offset(-2.5).constraint 
     make.left.equalTo(view).offset(0) 
     make.right.equalTo(view).offset(0) 
    } 
} 

func updateProgressViewConstraint() { 
    let navBarHeight = navigationBar.frame.size.height 
    progressViewTopConstraint?.updateOffset(navigationBar.hidden ? 0 : navBarHeight - 2.5) 
    view.bringSubviewToFront(progressView) 
} 

override func viewWillLayoutSubviews() { 
    updateProgressViewConstraint() 
    super.viewWillLayoutSubviews() 
} 

updateViewConstraints()是更好的方法來覆蓋,但有問題在這種情況下使用新的hidesBarOnSwipe(錯誤定位progressView)。

注意:在UINavigationController中執行此操作時,progressView仍會跳轉(即在UINavigationBar完成轉換後設置的位置),所以現在我將它移動到View本身。

編輯:將它放置在視圖本身中修復了欄的跳躍,但當然不允許將UIProgressView放置在UINavigationBar中。