更改 NSLayoutConstraint 的常量
Posted
技术标签:
【中文标题】更改 NSLayoutConstraint 的常量【英文标题】:Changing the constant of a 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。这个问题对我来说似乎很奇怪,我不太确定从这里做什么。感谢您的帮助。
【问题讨论】:
【参考方案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 秒会有所不同吗?以上是关于更改 NSLayoutConstraint 的常量的主要内容,如果未能解决你的问题,请参考以下文章
NSLayoutConstraint 的 Unsatisfiable Constraint 以编程方式更改 - swift
NSLayoutConstraint 不使用 UIView.animate 进行动画处理
在 iOS7 中设置 NSLayoutConstraint 常量
在 NSLayoutConstraint 上更新“常量”失败,并显示“无法分配给 'constraint' 中的 'constant'”