[英]Updating Constraints for ProgressView with hidesBarsOnSwipe
我试图在UINavigationBar内部显示进度条,如此处所述: 在UINavigationController的UINavigationBar内部或顶部显示UIProgressView 。
在Swift中完成后,自定义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被放到StatusBar下。
我试图在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时效果不佳:当隐藏/显示带有Rotation的导航栏(垂直紧凑时)或Swipe时,
有什么建议么?
尽管可以通过代码使用自动布局约束来执行此操作,但是使用组件(此处为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内。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.