【发布时间】: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