Swift 4中如何以编程方式查找并操作UIView的leading约束
嘿,在Swift 4里搞定UIView的leading约束查找和操作其实没那么复杂,我给你整理几种实战里常用的方案,一步步来:
leading约束本质是当前视图和父视图(或其他参照视图)之间的布局关系,所以查找的时候要注意约束所在的层级,下面是几种靠谱的方法:
1. 提前保存约束引用(最推荐)
如果是你自己编程创建约束,最省心的方式就是直接把leading约束保存为一个属性,完全不用后续查找。比如用Auto Layout锚点(NSLayoutAnchor)创建时:
class YourViewController: UIViewController { // 提前声明属性保存约束 private var customViewLeadingConstraint: NSLayoutConstraint! override func viewDidLoad() { super.viewDidLoad() let customView = UIView() customView.translatesAutoresizingMaskIntoConstraints = false customView.backgroundColor = .blue view.addSubview(customView) // 创建leading约束并保存 customViewLeadingConstraint = customView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20) // 批量激活约束 NSLayoutConstraint.activate([ customViewLeadingConstraint, customView.topAnchor.constraint(equalTo: view.topAnchor, constant: 30), customView.widthAnchor.constraint(equalToConstant: 150), customView.heightAnchor.constraint(equalToConstant: 150) ]) } }
这种方式后续操作约束直接用customViewLeadingConstraint就行,完全避免查找的麻烦,是我平时开发首选的方案。
2. 通过约束标识符(identifier)查找
如果约束是Storyboard创建的,或者你不想提前保存引用,可以给约束设置一个唯一的identifier,之后通过遍历查找:
设置标识符:
如果是编程创建约束:
let leadingConstraint = NSLayoutConstraint(item: customView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 20) // 设置唯一标识符 leadingConstraint.identifier = "CustomViewLeadingConstraint" view.addConstraint(leadingConstraint)
如果是Storyboard创建,直接在属性面板里给约束加Identifier即可。
查找约束:
if let leadingConstraint = view.constraints.first(where: { $0.identifier == "CustomViewLeadingConstraint" }) { // 找到目标约束,接下来可以操作它 }
注意:如果约束是添加到父视图的,就遍历父视图的constraints数组;如果是视图自身的约束(比如和其他兄弟视图的leading关系),就遍历自身的constraints。
3. 遍历约束属性匹配查找
如果没设置标识符,也可以通过匹配约束的firstItem、firstAttribute等属性来查找,适合临时场景:
// 假设要找customView相对于父视图的leading约束 if let leadingConstraint = customView.superview?.constraints.first(where: { // 判断约束的第一个元素是customView,且属性是leading ($0.firstItem as? UIView) == customView && $0.firstAttribute == .leading && // 判断约束的第二个元素是父视图,且属性是leading ($0.secondItem as? UIView) == customView.superview && $0.secondAttribute == .leading }) { // 找到目标约束 }
这种方式要注意约束的方向,比如有些约束可能是父视图的leading等于子视图的leading(虽然很少见),所以要根据实际情况调整判断条件。
找到约束后,常见的操作有这些:
1. 修改约束的constant值(最常用)
调整左边距只需要修改constant,记得触发布局更新,要动画的话把layoutIfNeeded放在动画闭包里:
// 修改左边距为50 leadingConstraint.constant = 50 // 无动画更新布局 view.layoutIfNeeded() // 带动画更新布局 UIView.animate(withDuration: 0.3) { self.view.layoutIfNeeded() }
2. 激活/禁用约束
临时切换布局时可以禁用约束,之后再激活:
// 禁用约束 leadingConstraint.isActive = false // 重新激活约束(会自动添加到合适的视图层级) leadingConstraint.isActive = true
3. 调整约束优先级
如果有布局冲突,可以降低约束的优先级(优先级范围1-1000,1000是系统强制的required,不能改):
// 设置优先级为999(低于required) leadingConstraint.priority = UILayoutPriority(rawValue: 999)
内容的提问来源于stack exchange,提问作者Meenakshi Borade

