为何UIView的constraints属性为空?heightAnchor创建约束却正常?
问题原因&解决方案
哈哈,这个坑我当初踩过好多次!其实核心是你搞混了UIView.constraints属性的真正含义~
1. 先搞懂constraints属性到底存的是什么
苹果文档里说这个属性是“视图所持有的约束”,但这里的“持有”不是指所有和这个视图相关的约束,而是指这个视图作为约束容器的约束——也就是当你调用view.addConstraint(_:)把约束添加到这个视图上时,这个约束才会出现在它的constraints数组里。
2. 为什么width/heightAnchor的约束能在constraints里找到?
当你用view.heightAnchor或widthAnchor创建约束并设置isActive = true时,系统会自动把约束添加到这个视图本身(因为这类约束只涉及单个视图,苹果规定这类约束的容器就是视图自己)。所以你打印view.constraints时,自然能看到它们。
举个例子:
let widthConstraint = myView.widthAnchor.constraint(equalToConstant: 150) widthConstraint.isActive = true // 此时 myView.constraints 里会包含这个 widthConstraint
3. 为什么你手动创建的约束不在constraints里?
大概率你创建的是跨视图的约束(比如约束视图A的leading到视图B的trailing)。这类约束涉及两个视图,系统激活它时,会自动把约束添加到两个视图的共同父视图上,而不是其中某一个子视图。所以你去看子视图的constraints数组,自然是空的——约束根本没存在这里!
比如:
let leadingConstraint = NSLayoutConstraint( item: viewA, attribute: .leading, relatedBy: .equal, toItem: viewB, attribute: .trailing, multiplier: 1, constant: 8 ) leadingConstraint.isActive = true // 此时约束被添加到 viewA 和 viewB 的共同父视图,viewA.constraints 里找不到它 // 要找的话得去 parentView.constraints 里找
4. 怎么查看所有影响某个视图的约束?
如果你想拿到所有和这个视图相关、影响它布局的约束,别用constraints属性,用这个方法:
// 获取影响水平布局的所有约束 let horizontalConstraints = myView.constraintsAffectingLayout(for: .horizontal) // 获取影响垂直布局的所有约束 let verticalConstraints = myView.constraintsAffectingLayout(for: .vertical)
这个方法会返回所有关联到该视图的约束,不管它们被存在哪个父视图里。
内容的提问来源于stack exchange,提问作者Ninja
相关产品推荐
相关产品推荐

