有啥方法可以在 Swift 中以编程方式获取所有应用的自动布局约束

Posted

技术标签:

【中文标题】有啥方法可以在 Swift 中以编程方式获取所有应用的自动布局约束【英文标题】:Is there any way to get all the applied Auto-layout constrains programatically in Swift有什么方法可以在 Swift 中以编程方式获取所有应用的自动布局约束 【发布时间】:2018-09-11 07:11:48 【问题描述】:

我想在没有任何参考的情况下使用情节提要获得所有应用约束的参考:

我尝试了很多方法,但无法找到确切的解决方案:

我的方法如下:

    if let constraint = (self.constraints.filter$0.firstAttribute == .height.first) 


使用上述方法,我只能找出高度。

if let topConstraint = (self.constraints.filter$0.firstAttribute == .top.first) 
            topConstraint.constant = 150//topMargin
        
if let leadingConstraint = (self.constraints.filter$0.firstAttribute == .leading.first) 
            leadingConstraint.constant = 60 //leadingMargin
        

对于 topConstraint 和leadingConstraint 我得到了零。

self.constraints

self.constraints 只给出一个参考,即只有高度,即使我在同一个视图上应用了前导、尾随和底部约束。

注意:我不想从情节提要中获取参考,因此请不要建议该解决方案。我想要动态引用。

我正在寻找类似以下的方法:

 if let topConstraint = (self.constraints.filter$0.firstAttribute == .top.first) 
                topConstraint.constant = 150//topMargin
            
   if let leadingConstraint = (self.constraints.filter$0.firstAttribute == .leading.first) 
                leadingConstraint.constant = 60 //leadingMargin
            
   if let trailingConstraint = (self.constraints.filter$0.firstAttribute == .trailing.first) 
                trailingConstraint.constant = 70//leadingMargin
            
   if let bottomConstraint = (self.constraints.filter$0.firstAttribute == .bottom.first) 
                bottomConstraint.constant = 150//49 + bottomMargin
            

但不幸的是,上面的一个对我不起作用:(

【问题讨论】:

How to get constraints from UIView Programmatically的可能重复 @bhatejaud我已经使用情节提要应用了我的约束,并希望在运行时访问它的引用。这两个问题是不同的。如果您有任何解决方案,请建议我。 @Alok 我认为您可以通过标识符获得约束。这是链接苹果文档developer.apple.com/documentation/uikit/nslayoutconstraint/… 嗯...实际上,您的问题让我说:您这样做的目的是什么?!即一般问题是什么? @chiragshah 感谢您的建议,但我不想采用这种方法,因为我有 50 多个控制器并且想在任何地方进行更改。所以这种方法会导致运行时错误。你有没有像问题中给出的身高一样的方法?如果让约束 = (self.constraints.filter$0.firstAttribute == .height.first) 【参考方案1】:

对于单个视图,您可以轻松获取与其相关的所有约束

for constraint in view.constraints 
   print(constraint.constant)

而对于特定视图的所有子视图,你可以得到这样的

func getAllTheConstraintConstantsFor(view:UIView) 

   for constraint in view.constraints 
      print(constraint.constant)
   

   for subview in view.subviews 
      self.getAllTheConstraintConstantsFor(view: subview)
   

在这里你可以通过self.view,你会得到所有的约束。

【讨论】:

self.constraints 只给出高度。我已经在我的问题中解释过了。 我没有为任何视图设置高度约束,我也得到了所有前导和尾随约束【参考方案2】:

参考this答案

对于像UIButton 这样的视图,您可以使用此代码找到top 约束。

extension UIButton 

    func findTopConstraint() -> NSLayoutConstraint? 
        for constraint in (self.superview?.constraints)! 
            if isTopConstraint(constraint: constraint) 
                return constraint
            
        
        return nil
    

    func isTopConstraint(constraint: NSLayoutConstraint) -> Bool 
        return (firstItemMatchesTopConstraint(constraint: constraint) || secondItemMatchesTopConstraint(constraint: constraint))
    

    func firstItemMatchesTopConstraint(constraint: NSLayoutConstraint) -> Bool 
        return (constraint.firstItem as? UIButton == self && constraint.firstAttribute == .top )
    

    func secondItemMatchesTopConstraint(constraint: NSLayoutConstraint) -> Bool 
        return (constraint.secondItem as? UIButton  == self && constraint.secondAttribute == .top)
    

要在UIButton 上获得top 约束,只需使用此代码

button.findTopConstraint()!

同样,您可以在任何视图上找到任何约束。

注意:您需要自己管理nil 案例。

【讨论】:

@sunny我得到 view.constraints 等于零,即使我使用情节提要对同一个视图应用了约束。 @Alok 你提到你得到了高度限制。 我不知道我的代码中发生了什么。对于某些视图,我只得到高度约束,而对于其他视图总是为零。请在此处查看我的另一个问题:***.com/q/52272096/3024579 使用view.constraint,您将只获得视图的宽度或高度 它是 top 不是 topconstraint 。这是NSLayoutAttributeattribute

以上是关于有啥方法可以在 Swift 中以编程方式获取所有应用的自动布局约束的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中以编程方式创建 NSTextField

获取 Button 和 Textfield 数据,当它们在 swift 5 中以编程方式添加时

在 iOS Swift 3 中以编程方式添加 Web 视图时如何在 UIWebView 中获取响应状态代码?

有没有办法在Swift中以编程方式设置NSCollectionView?

使用 Cocoa 在 Swift 4.0 中以编程方式创建复选框的标准方法是啥?

如何在 Swift 中以编程方式更改 UIButton 状态