确定具有不同优先级的两个布局约束中的哪一个是确定它们影响的 dimension/anchor 的值
Determining which of two layout constraints with different priorities is determining the value of the dimension/anchor they affect
假设我有两个具有不同优先级的 NSLayoutConstraint,它们都会影响某些视图的高度 (middleView)。
下图,middleView固定在topView的底部,高度为500,除非bottomView的顶部迫使它变小。
// topView and bottomView have well-defined constraints, and middleView has well defined x-axis/width constraints not shown here
middleView.topAnchor.constraint(isEqual: topView.bottomAnchor).isActive = true
let heightConstraint = middleView.heightAnchor.constraint(isEqualToConstant: 500)
heightConstraint.priority = UILayoutPriority.high
heightConstraint.isActive = true
let bottomConstraint = middView.bottomAnchor.constraint(isLessThanOrEqualTo: bottomView.topAnchor, constant: someMargin)
bottomConstraint.isActive = true // priority is .required by default
除了检查我的视图高度是否为 500 之外,是否有其他方法可以确定这两个约束中的哪一个是 "in effect"?说bottomView处于这样一个位置,如果强制middleView的高度小于500,heightConstraint是否有一些属性来确定它被一个比它自己的优先级更高的约束绕过?
我想将 heightConstraint 用作某种 'switch',当满足时触发某些东西。
看来不可能。另一种方法是将所讨论的 dimension/anchor 常量与可能的值进行比较。
这无法回答,因为 两者 可能都有一些影响。即使无法满足非必需的约束,它也会影响布局。来自 Auto Layout Guide:
Even if an optional constraint cannot be satisfied, it can still influence the layout. If there is any ambiguity in the layout after skipping the constraint, the system selects the solution that comes closest to the constraint. In this way, unsatisfied optional constraints act as a force pulling views towards them.
自动布局使用约束求解器来计算其值。 (我相信它仍在使用 Cassowary 或接近它的东西。)约束求解器基本上是线性代数引擎。您将一堆线性方程式放入一个矩阵中,然后尝试求解某个向量,使一切成为可能 "best." 这种方法的一个权衡是一切都一起求解,而且并不总是很明显 为什么 选择了一个特定的值。之所以如此,是因为它是整体解决方案的一部分。 (这样,CSP 系统与机器学习系统非常相似。它们给出 "correct," 的答案,但它们并不总是以分支方式(如果逻辑可以的话)提供其推理的分步步骤。它是为什么它们调试起来如此具有挑战性。)
对于你的问题,我会将你的逻辑建立在你真正关心的事情之上。 "A constraint fired" 从来都不是您真正关心的事情(特别是因为约束不 "fire")。您通常关心结果中的某些内容(例如最终高度),因此您应该检查一下。
假设我有两个具有不同优先级的 NSLayoutConstraint,它们都会影响某些视图的高度 (middleView)。
下图,middleView固定在topView的底部,高度为500,除非bottomView的顶部迫使它变小。
// topView and bottomView have well-defined constraints, and middleView has well defined x-axis/width constraints not shown here
middleView.topAnchor.constraint(isEqual: topView.bottomAnchor).isActive = true
let heightConstraint = middleView.heightAnchor.constraint(isEqualToConstant: 500)
heightConstraint.priority = UILayoutPriority.high
heightConstraint.isActive = true
let bottomConstraint = middView.bottomAnchor.constraint(isLessThanOrEqualTo: bottomView.topAnchor, constant: someMargin)
bottomConstraint.isActive = true // priority is .required by default
除了检查我的视图高度是否为 500 之外,是否有其他方法可以确定这两个约束中的哪一个是 "in effect"?说bottomView处于这样一个位置,如果强制middleView的高度小于500,heightConstraint是否有一些属性来确定它被一个比它自己的优先级更高的约束绕过?
我想将 heightConstraint 用作某种 'switch',当满足时触发某些东西。
看来不可能。另一种方法是将所讨论的 dimension/anchor 常量与可能的值进行比较。
这无法回答,因为 两者 可能都有一些影响。即使无法满足非必需的约束,它也会影响布局。来自 Auto Layout Guide:
Even if an optional constraint cannot be satisfied, it can still influence the layout. If there is any ambiguity in the layout after skipping the constraint, the system selects the solution that comes closest to the constraint. In this way, unsatisfied optional constraints act as a force pulling views towards them.
自动布局使用约束求解器来计算其值。 (我相信它仍在使用 Cassowary 或接近它的东西。)约束求解器基本上是线性代数引擎。您将一堆线性方程式放入一个矩阵中,然后尝试求解某个向量,使一切成为可能 "best." 这种方法的一个权衡是一切都一起求解,而且并不总是很明显 为什么 选择了一个特定的值。之所以如此,是因为它是整体解决方案的一部分。 (这样,CSP 系统与机器学习系统非常相似。它们给出 "correct," 的答案,但它们并不总是以分支方式(如果逻辑可以的话)提供其推理的分步步骤。它是为什么它们调试起来如此具有挑战性。)
对于你的问题,我会将你的逻辑建立在你真正关心的事情之上。 "A constraint fired" 从来都不是您真正关心的事情(特别是因为约束不 "fire")。您通常关心结果中的某些内容(例如最终高度),因此您应该检查一下。