我可以使用自动布局在 UIScrollView 中包含灵活的 space 吗?

Can I include flexible space in a UIScrollView using Autolayout?

我有一个滚动视图,其中包含用于登录应用程序的不同选项。

我想将两个按钮固定到视图底部,除非视图变得太小,否则视图应该滚动。

"Login" 和 "Facebook" 之间没有约束,这会导致臭名昭著的 "ambiguous content height"。包含 "top space to view" 约束意味着按钮不会固定在底部。

有没有办法单独使用自动布局来包含此 "flexible space"?不行怎么办?

请检查我做了什么。也许这会对你有所帮助。

  • 一目了然并添加 fb 和 google 按钮初始化。
  • 为 Scrollview 提供等宽和等高的视图。水平和垂直居中,这样 Scrollview 就会得到它的内容大小。所以如果屏幕增加,scrollview增加,UIView也会增加。
  • 将 Fb 和 google 设置为 UIView 的底部约束,所以如果屏幕增加你的按钮将坚持到底部并不重要。

其他的东西直接放在UIScrollview中或者添加到UIView中。

请检查下面screenshot.Hope它有帮助。


OP编辑:

如果屏幕很短,这个答案需要做一些额外的工作来停止按钮重叠。 (我不能 post 确切的代码,因为它是我公司的 IP,但作为一个概述:)

关于布局子视图:

  • 通过相交检查社交登录视图的框架和滚动视图底部的视图是否重叠。
    • 两个框架应该在同一个坐标 space。例如转换为 window space.
  • 将内容视图的高度限制增加该交叉点的高度(可能还有一点额外的填充)
  • 将包含社交登录的视图框架向下移动相同的量。

看看这个我有一个案例和你的一样。看看 - 这一定会帮助您解决约束冲突。

创建 UIScrollView 并使用 superview

设置约束
// Create scrollview to display content
self.scrollView = UIScrollView()
self.scrollView.delegate = self
self.scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(self.scrollView)
scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.Interactive

// Visual formatting constraints of scrollview horizontal-vertical alignment with respect to view
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["scrollView" : scrollView]))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["scrollView" : scrollView]))

创建scrollView后,为scrollview创建子视图并定义其约束:

[这里的VariableView是一个不同的class,它是UIView的子class,不包含在代码中,仅供参考。将您的视图替换为 VariableView]

func createQuestionControls() {

    var previousControlView : VariableView! = nil

    for variable in self.consultation.variables {

        // Create custom view to add controls
        var controlView : VariableView! = VariableView()
        controlView.customTextDelegate? = self
        controlView.setVariableView(variable as! Variable)
        controlView.backgroundColor = UIColor.clearColor()
        controlView.setTranslatesAutoresizingMaskIntoConstraints(false)

        controlView.endEditing(true)

        self.scrollView.addSubview(controlView)

        // TOP Horizontal constraint
        var metrices = ["width" : self.view.bounds.width]
        self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[controlView(width)]", options: NSLayoutFormatOptions(0), metrics: metrices, views: ["controlView" : controlView]))

        if previousControlView == nil {

            // Top vertical constraint
            self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[controlView]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["controlView" : controlView]))
        } else {

            // Top constraint to previous view
            self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[previousControlView]-(10)-[controlView]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["controlView" : controlView, "previousControlView" : previousControlView]))
        }
        previousControlView = controlView
    }

    // This below constraints will increase UIScrollView content size
    var constraint1 = NSLayoutConstraint.constraintsWithVisualFormat("H:[previousControlView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["previousControlView" : previousControlView])
    self.scrollView.addConstraints(constraint1)

    var constraint2 = NSLayoutConstraint.constraintsWithVisualFormat("V:[previousControlView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["previousControlView" : previousControlView])
    self.scrollView.addConstraints(constraint2)
}

这里需要注意的一点是,如果在UIScrollView中有多个子视图,则使用bottom view(scrollView中最后附加的子视图),在constraint1和[=19中使用=] 变量。