gpt4 book ai didi

ios - 使用 hidesBarsOnSwipe 更新 ProgressView 的约束

转载 作者:行者123 更新时间:2023-11-28 08:53:49 33 4
gpt4 key购买 nike

我正在尝试在 UINavigationBar 中显示一个进度条,就像这里讨论的那样:Showing a UIProgressView inside or on top of a UINavigationController's UINavigationBar .

自定义 UINavigationController 类在 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)
}
}

问题:一旦 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 的自动隐藏一起使用:当隐藏/显示带旋转的导航栏(垂直紧凑时)或滑动导航栏时

  • 纵向时 UINavigationBar 下方 30 像素,但是
  • 当 UINavigationBar 横向隐藏时在最顶部
  • 当 UINavigationBar 横向显示时不可见(被覆盖)

有什么建议吗?

最佳答案

虽然可以通过代码使用自动布局约束来完成此操作,但使用组件(此处为 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 本身。

编辑:将其放置在 View 中本身修复了栏的跳跃,但当然不允许将 UIProgressView 放置在 UINavigationBar 中。

关于ios - 使用 hidesBarsOnSwipe 更新 ProgressView 的约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33606645/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com