I am trying to show a progress bar inside of a UINavigationBar, like discussed here: Showing a UIProgressView inside or on top of a UINavigationController's UINavigationBar.
The custom UINavigationController class looks like this when done in Swift:
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)
}
}
The problem: As soon as the UINavigationBar is hidden automatically by OnSwipe/WhenVerticallyCompact the constraint stops working, i.e. the ProgressView is misplaced under the StatusBar.
I tried to update it in updateViewConstraints() and/or viewWillLayoutSubviews() which is the only way I currently see.
As the constant is already used for the position relative to the UINavigationBar separator (see linked SO thread), i tried this to test the updateViewContraints() for this case:
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)
}
Note the constant set to 30 for this test.
From doing this I can see that the constraint does not play nice with the automatic hiding of the UINavigationBar: When hiding/showing the Navigation Bar with Rotation (when vertically compact) or Swipe the Bar is
- 30 px under the UINavigationBar when in portrait, but
- at the very top when UINavigationBar is hidden in landscape
- invisible (covered) when UINavigationBar is shown in landscape
Any suggestions?