以编程方式将UIView大小调整到UIViewController的视图

时间:2015-02-14 23:51:57

标签: swift storyboard uikit autolayout

我正在尝试将UIView的大小调整为超级视图。除了在故事板中自动给出的视图外,这是有效的。因此,此代码适用于subview2,但subview的大小不适合其封闭视图。

import UIKit

extension UIView {
    func addConstraintsWithVFL(constraintsVFL: String, views: [String: UIView], metrics: [NSObject: AnyObject]? = nil, options: NSLayoutFormatOptions = NSLayoutFormatOptions.allZeros) {
        let mutableDict = (views as NSDictionary).mutableCopy() as NSMutableDictionary
        let constraints = NSLayoutConstraint.constraintsWithVisualFormat(constraintsVFL, options: options, metrics: metrics, views: mutableDict)
        self.addConstraints(constraints)
    }
}

class ViewController: UIViewController {

    @IBOutlet var subview : UIView!  // red, inside self.view
    @IBOutlet var subview2 : UIView! // blue, inside subview

    override func viewDidLoad() {
        super.viewDidLoad()
        var views : [String: UIView]
        views  = ["box": self.subview]//, "super": self.view]
        self.view.addConstraintsWithVFL("V:|-5-[box]-5-|", views: views)
        self.view.addConstraintsWithVFL("H:|-5-[box]-5-|", views: views)
        views  = ["box": self.subview2, "super": self.subview]
        self.view.addConstraintsWithVFL("V:|-5-[box]-5-|", views: views)
        self.view.addConstraintsWithVFL("H:|-5-[box]-5-|", views: views)
    }

}

故事板在任何地方都没有任何限制。结果如下所示:

enter image description here

如何使用AutoLayout将我的子视图的大小调整为整个UIView

1 个答案:

答案 0 :(得分:3)

通常,在IB中添加视图时,在IB中添加约束也更容易。那么你根本不必处理我在下面列举的所有问题。但是,如果您决定在IB中创建视图但是以编程方式添加约束,则应注意:

  1. 在Xcode 6中,如果您不在IB中添加约束,它将为您创建约束。选择红色或蓝色视图,然后转到尺寸检查器选项 + 命令 + 5 。在"约束"如果您没有定义任何约束,它可能会报告以下内容:

      

    所选视图没有约束。在构建时,将为视图生成显式的left,top,width和height约束。

  2. 如果你让Xcode添加这些约束以及你以编程方式添加的约束,在Xcode 6及更高版本中,你会看到如下警告:

      

    2015-02-14 21:44:59.766 AutoLayoutTest [22382:8773715]无法同时满足约束条件。

         

    以下列表中的至少一个约束可能是您不想要的约束。试试这个:(1)看看每个约束,并试着找出你不期望的东西; (2)找到添加了不需要的约束或约束的代码并修复它。 (注意:如果您正在查看您不了解的NSAutoresizingMaskLayoutConstraints,请参阅UIView属性的文档translatesAutoresizingMaskIntoConstraints)

    ( 
        "<NSIBPrototypingLayoutConstraint:0x7ff5a9c94770 'IB auto generated at build time for view with fixed frame' H:|-(0)-[UIView:0x7ff5a9c926c0](LTR)   (Names: '|':UIView:0x7ff5a9c93360 )>",
        "<NSLayoutConstraint:0x7ff5a9c99400 H:|-(5)-[UIView:0x7ff5a9c926c0]   (Names: '|':UIView:0x7ff5a9c93360 )>"
    )
    
         

    将尝试通过违反约束来恢复   

         

    在UIViewAlertForUnsatisfiableConstraints处创建一个符号断点,以便在调试器中捕获它。   UIView中列出的UIVonstraintBasedLayoutDebugging类别中的方法也可能有所帮助。

    但是,Xcode 5不会为您添加这些约束。

  3. 如果您决定以编程方式为您未以编程方式创建的视图添加约束,则在Xcode 6中您应该为视图添加自己的约束(例如&#34;重置为在IB中建议约束&#34;选项,如果你想为它创建一个完整的集合:

    enter image description here

    然后查看所有单个约束并标记它们以在构建时删除:

    enter image description here

  4. 或者,如果您想在添加自己的约束之前以编程方式删除IB生成的约束,您可以执行以下操作:

    removeConstraintsBetweenFirstItem(view, secondItem: redView)
    removeConstraintsBetweenFirstItem(redView, secondItem: blueView)
    

    其中

    func removeConstraintsBetweenFirstItem(firstItem: UIView, secondItem: UIView) {
        let constraintsToRemove = firstItem.constraints().filter() { (constraint) -> (Bool) in
            if constraint.firstItem as UIView == secondItem {  // in Swift 1.2, use as!
                return true
            }
            if let constraintSecondItem = constraint.secondItem as? UIView {
                return constraintSecondItem == secondItem
            }
            return false
        }
        firstItem.removeConstraints(constraintsToRemove)
    }
    

    这比仅仅执行以下操作更安全,这比我更喜欢不加区分:

    view.removeConstraints(view.constraints())
    redView.removeConstraints(redView.constraints())
    
  5. 完成后,您现在可以按编程方式添加约束,如下所示:

    @IBOutlet weak var redView: UIView!
    @IBOutlet weak var blueView: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        let views = ["redView" : redView, "blueView" : blueView]
        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-5-[redView]-5-|", options: nil, metrics: nil, views: views))
        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-5-[redView]-5-|", options: nil, metrics: nil, views: views))
        redView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-5-[blueView]-5-|", options: nil, metrics: nil, views: views))
        redView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-5-[blueView]-5-|", options: nil, metrics: nil, views: views))
    }
    

    产生以下结果,没有任何不良警告:

    enter image description here

  6. 如果您想诊断约束,可以运行该应用程序,然后单击视图调试器:

    enter image description here

    或者,您可以暂停执行应用程序,并在(lldb)提示符下输入

    po [[UIWindow keyWindow] _autolayoutTrace]
    

    通过这些技巧中的任何一种,您都可以诊断出已添加到视图中的约束。