使用 constraintsWithVisualFormat 的自动布局效果不佳

Auto-layout with constraintsWithVisualFormat is not working well

我已设置滚动视图并向滚动视图添加约束。但它显示空白屏幕。请检查以下代码。

override func loadView()
    {
        super.loadView()
        scrollView = UIScrollView(frame:CGRectZero)
        scrollView.backgroundColor = UIColor.whiteColor()

        scrollView.sizeToFit()

        self.view.addSubview(scrollView)
        scrollView.backgroundColor = UIColor.blueColor()

        contentView = UIView()
//        contentView.setTranslatesAutoresizingMaskIntoConstraints(false)
        contentView.backgroundColor = UIColor.redColor()
        scrollView.addSubview(contentView)

        var viewBindingsDictBoth = [String: AnyObject]()
        viewBindingsDictBoth["scrollView"] = scrollView
        viewBindingsDictBoth["contentView"] = contentView
        viewBindingsDictBoth["mainView"] = self.view


        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[scrollView]-0-|",options: [], metrics: nil,  views:viewBindingsDictBoth))

        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[scrollView]-0-|",options: [], metrics: nil, views:viewBindingsDictBoth))

        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[contentView]|",options: [], metrics: nil, views:viewBindingsDictBoth))
        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[contentView]|",options: [], metrics: nil, views:viewBindingsDictBoth))

        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[contentView(==mainView)]",options: [], metrics: nil, views:viewBindingsDictBoth))

        self.view.contentMode = UIViewContentMode.Redraw
    }

提前致谢..

在 viewcontroller 的 loadView() 方法中,您需要创建一个根视图。您现在的根视图是 nil
view = UIView()

我通常发现没有必要重写 loadView 除非我真的试图让基本视图 (self.view) 成为 UIView 的不同子类。 loadView 用于初始化 self.view 的值,您忘记这样做了。

对于您的情况,为了便于阅读,我建议将视图初始化移动到 viewDidLoad

override func viewDidLoad() {
    // Do your init here
}

你最想念的是

scrollView.translatesAutoresizingMaskIntoConstraints = false

contentView.translatesAutoresizingMaskIntoConstraints = false

我认为您的某些约束并不完美,但最大的问题是每个视图都默认使用其自动调整属性进行定位。这些将与您的约束发生冲突。

来自UIView.translatesAutoresizingMaskIntoConstraints documentation

Note that the autoresizing mask constraints fully specify the view’s size and position; therefore, you cannot add additional constraints to modify this size or position without introducing conflicts. If you want to use Auto Layout to dynamically calculate the size and position of your view, you must set this property to false, and then provide a non ambiguous, nonconflicting set of constraints for the view.

(强调我的)

你有几个错误:

    override func loadView()
        {
            super.loadView()
            scrollView = UIScrollView(frame:CGRectZero)
            scrollView.backgroundColor = UIColor.whiteColor()
            scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)

            // No need for sizeToFit with autoLayout
            //scrollView.sizeToFit()

            self.view.addSubview(scrollView)
            scrollView.backgroundColor = UIColor.blueColor()

            contentView = UIView()

           //Always set TranslatesAutoresizingMaskIntoConstraints to false, on every view that users AutoLayout

            contentView.setTranslatesAutoresizingMaskIntoConstraints(false)
            contentView.backgroundColor = UIColor.redColor()
            scrollView.addSubview(contentView)

            var viewBindingsDictBoth = [String: AnyObject]()
            viewBindingsDictBoth["scrollView"] = scrollView
            viewBindingsDictBoth["contentView"] = contentView
            viewBindingsDictBoth["mainView"] = self.view


            view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[scrollView]-0-|",options: [], metrics: nil,  views:viewBindingsDictBoth))

            view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[scrollView]-0-|",options: [], metrics: nil, views:viewBindingsDictBoth))

            view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[contentView]|",options: [], metrics: nil, views:viewBindingsDictBoth))
            view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[contentView]|",options: [], metrics: nil, views:viewBindingsDictBoth))

            view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[contentView(==mainView)]",options: [], metrics: nil, views:viewBindingsDictBoth))

           // self.view.contentMode = UIViewContentMode.Redraw
        }