Fat*_*tie 16 ios nslayoutconstraint swift
说我有一个UIView,
class CleverView: UIView
Run Code Online (Sandbox Code Playgroud)
在自定义类中,我想这样做:
func changeWidth() {
let c = ... find my own layout constraint, for "width"
c.constant = 70 * Gameinfo.ImportanceOfEnemyFactor
}
Run Code Online (Sandbox Code Playgroud)
同样地,我希望能够像这样"找到",约束(或者我猜,所有约束,可能有不止一个)附加到四个边缘之一.
因此,要查看附加到我身上的所有约束,并找到任何宽度/高度,或者确实与给定(例如,"左")边缘相关的任何约束.
有任何想法吗?
也许值得注意这个问题
请注意(显然)我问如何动态/编程地执行此操作.
(是的,你可以说"链接到约束"或"使用ID" - 质量保证的重点是如何动态地找到它们并动态地工作.)
如果您不熟悉约束,请注意.constraints
只是为您提供存储在那里的结尾.
sta*_*kri 22
实际上有两种情况:
重复.对于两个视图之间的约束.事实上,iOS确实将它们存储在最低的共同祖先中.因此,通过搜索视图的所有祖先,总是可以找到视图的约束.
因此,我们需要检查视图本身及其所有超视图的约束.一种方法可能是:
extension UIView {
// retrieves all constraints that mention the view
func getAllConstraints() -> [NSLayoutConstraint] {
// array will contain self and all superviews
var views = [self]
// get all superviews
var view = self
while let superview = view.superview {
views.append(superview)
view = superview
}
// transform views to constraints and filter only those
// constraints that include the view itself
return views.flatMap({ $0.constraints }).filter { constraint in
return constraint.firstItem as? UIView == self ||
constraint.secondItem as? UIView == self
}
}
}
Run Code Online (Sandbox Code Playgroud)
在获得关于视图的所有约束之后,您可以应用所有类型的过滤器,我想这是最困难的部分.一些例子:
extension UIView {
// Example 1: Get all width constraints involving this view
// We could have multiple constraints involving width, e.g.:
// - two different width constraints with the exact same value
// - this view's width equal to another view's width
// - another view's height equal to this view's width (this view mentioned 2nd)
func getWidthConstraints() -> [NSLayoutConstraint] {
return getAllConstraints().filter( {
($0.firstAttribute == .width && $0.firstItem as? UIView == self) ||
($0.secondAttribute == .width && $0.secondItem as? UIView == self)
} )
}
// Example 2: Change width constraint(s) of this view to a specific value
// Make sure that we are looking at an equality constraint (not inequality)
// and that the constraint is not against another view
func changeWidth(to value: CGFloat) {
getAllConstraints().filter( {
$0.firstAttribute == .width &&
$0.relation == .equal &&
$0.secondAttribute == .notAnAttribute
} ).forEach( {$0.constant = value })
}
// Example 3: Change leading constraints only where this view is
// mentioned first. We could also filter leadingMargin, left, or leftMargin
func changeLeading(to value: CGFloat) {
getAllConstraints().filter( {
$0.firstAttribute == .leading &&
$0.firstItem as? UIView == self
}).forEach({$0.constant = value})
}
}
Run Code Online (Sandbox Code Playgroud)
//编辑:增强的示例并在评论中阐明了他们的解释
我猜你可以使用约束属性UIView
.constraints
基本上返回一个直接赋给UIView的约束数组.它不能让你获得超级视图所包含的约束,例如前导,尾随,顶部或底部,但宽度和高度约束由View本身保持.对于superview的约束,您可以遍历superview的约束.让我们说聪明的观点有这些限制:
class CleverView: UIView {
func printSuperViewConstriantsCount() {
var c = 0
self.superview?.constraints.forEach({ (constraint) in
guard constraint.secondItem is CleverView || constraint.firstItem is CleverView else {
return
}
c += 1
print(constraint.firstAttribute.toString())
})
print("superview constraints:\(c)")
}
func printSelfConstriantsCount() {
self.constraints.forEach { (constraint) in
return print(constraint.firstAttribute.toString())
}
print("self constraints:\(self.constraints.count)")
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
顶部
领先
尾随
上海华约束:3
高度
自我约束:1
基本上,您可以查看NSLayoutConstraint类以获取有关特定约束的信息.
要打印约束的名称,我们可以使用此扩展名
extension NSLayoutAttribute {
func toString() -> String {
switch self {
case .left:
return "left"
case .right:
return "right"
case .top:
return "top"
case .bottom:
return "bottom"
case .leading:
return "leading"
case .trailing:
return "trailing"
case .width:
return "width"
case .height:
return "height"
case .centerX:
return "centerX"
case .centerY:
return "centerY"
case .lastBaseline:
return "lastBaseline"
case .firstBaseline:
return "firstBaseline"
case .leftMargin:
return "leftMargin"
case .rightMargin:
return "rightMargin"
case .topMargin:
return "topMargin"
case .bottomMargin:
return "bottomMargin"
case .leadingMargin:
return "leadingMargin"
case .trailingMargin:
return "trailingMargin"
case .centerXWithinMargins:
return "centerXWithinMargins"
case .centerYWithinMargins:
return "centerYWithinMargins"
case .notAnAttribute:
return "notAnAttribute"
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4428 次 |
最近记录: |