【问题标题】:Changing the constant of a NSLayoutConstraint更改 NSLayoutConstraint 的常量
【发布时间】:2017-08-14 03:17:15
【问题描述】:

背景

我正在尝试使用动画和非动画选项进行相当标准的 NSLayoutConstraint 常量更新。为了给你一些背景知识,我有一个名为 ProgressView 的 UIView 子类。在 ProgressView 中,有 Progress Bar UIView。 Progress Bar UIView 作为引用插座progressBar 连接到 ProgressView 类。以下是故事板中相当简单的层次结构的外观:

您可能已经猜到了,我正在构建一个自定义进度条。 ProgressView UIView 是“轨道”,Progress Bar UIView 是“填充”。计划是使用 Progress Bar UIView 的尾随约束来更改进度。


现有配置

Progress Bar UIView 的约束设置为与超级视图(Progress View)齐平:

Progress Bar UIView 的尾随约束作为强出口连接到 ProgressView 类:@IBOutlet var trailingConstraint: NSLayoutConstraint!

在 ProgressView 类中,有一个setProgress 函数。这个函数是从包含 ProgressView 的 ViewController 中调用的。下面是 cmets 的函数,解释了它是如何工作的:

 public func setProgress(_ progress: Double, animationDuration: Double) {

    // Pre-conditions
    guard progress >= 0.0 && progress <= 1.0 && animationDuration >= 0.0 else {
        return
    }

    // Calculate the new constraint constant based on the progress
    let newConstant = CGFloat(1 - progress) * self.bounds.size.width

    // If the update should be made without animation, just make the change and return
    guard animationDuration > 0.0 else {
        trailingConstraint.constant = newConstant            
        return
    }

    // Set the constraint first
    self.trailingConstraint.constant = newConstant

    // Animate!
    UIView.animate(withDuration: animationDuration) {
        self.layoutIfNeeded()
    }

}

问题

如你所见,这个函数可以在有动画和没有动画的情况下更新进度。但是,当从 ViewController 调用时,两者都不起作用。尾随约束常量似乎保持为 0,进度条填满整个轨道。


尝试的解决方案

我已经尝试在每个位置和配置中调用layoutIfNeeded()setNeedsLayout() (在self [其中self 是ProgressView] 和progressBar)。我尝试使用DispatchQueue.main.async 将代码显式放在主线程上。作为一个基本事实测试,我尝试将 trailingConstraint 出口连接到 ViewController 本身,并从 viewDidAppear()viewDidLayoutSubviews() 方法更新常量。没有任何效果。


正确方向的可能提示

这是奇怪的部分。进度条出现在屏幕上,但是当我调试视图层次结构时,进度条看起来是正确的。 trailingConstraint 常量似乎设置正确。

我在 iOS 10 设备上进行测试并运行 Xcode 8.3.3。这个问题对我来说似乎很奇怪,我不太确定从这里做什么。感谢您的帮助。

【问题讨论】:

    标签: ios swift uiview nslayoutconstraint


    【解决方案1】:

    我遇到了同样的问题。我的问题是通过改变动画中的常量来解决的。试试这个:

     UIView.animate(withDuration: 0.2) { 
        self.trailingConstraint.constant = newConstant
        self.layoutIfNeeded()
        }
    

    【讨论】:

    • 我已经尝试了 layoutIfNeeded 和 constant 在动画外部,其中 layoutIfNeeded 内部。我已经尝试过常量和 layoutIfNeeded 里面。不幸的是,没有一个工作。
    • 将这一行 self.trailingConstraint.constant = newConstant 放到动画块之外
    • 你给的动画持续时间是 0.2 秒吗。试试看。这就像一种 hack
    • @Dev_Tandel 我试过了。不幸的是没有工作。在我的 setProgress 方法中,我还在警卫内进行了非动画约束更改。那也不行。
    • @Arnav 我尝试了硬编码的持续时间值(2 秒)。没用。 0.2 秒会有所不同吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    相关资源
    最近更新 更多