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

Posted

技术标签:

【中文标题】我可以使用自动布局在 UIScrollView 中包含灵活空间吗?【英文标题】:Can I include flexible space in a UIScrollView using Autolayout? 【发布时间】:2015-09-03 11:36:28 【问题描述】:

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

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

在“登录”和“Facebook”之间没有限制可能会导致臭名昭著的“内容高度不明确”。包含“顶部查看空间”约束意味着按钮不会锚定到底部。

有没有办法单独使用自动布局来包含这个“灵活空间”?如果没有怎么办?

【问题讨论】:

只需将 Facebook 和 Google 按钮固定到视图底部。其余的到顶部。这是你想要的吗? Having no constraint between "Login" and "Facebook" expectedly results in the infamous "ambiguous content height". 啊哈。因此,您的登录布局在滚动视图内,您正在寻找滚动它(反弹)的方式,并将 FB 和“字母”粘贴到底部。执行以下操作: 1. 将所有登录控件添加到“FreeForm”大小的视图中,将 FB 和 Google 固定到底部,将 container 视图添加到滚动视图中;在 viewDidLoad 或 viewWillAppear 处将 container 的高度更新为所需的大小。因此,您将获得弹跳屏幕和正确粘贴的按钮。 是的。 I have a scroll view that contains different options for logging into an application. 只有当“登录”和“Facebook”之间的空间达到足够小的阈值时,视图才会滚动。 我不确定你的意思。我从不设置内容大小。它是通过自动布局自动“计算出来”的。 【参考方案1】:

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

Take One View 并添加 fb 和 google 按钮初始化。 为滚动视图提供等宽和等高视图。并将水平和垂直居中,因此 Scrollview 将获得其内容大小。所以如果屏幕增加scrollview增加,UIView也会增加。 将 Fb 和 google 设置为 UIView 的底部约束,因此如果屏幕增大,您的按钮将始终保持在底部。

其他的都直接放到UIScrollview里面或者添加到UIView里面。

请查看下面的截图。希望对您有所帮助。


由 OP 编辑​​:

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

关于布局子视图:

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

【讨论】:

我知道这是如何工作的。等我回办公室试试看。 ?? 这对除了最小的屏幕之外的所有屏幕都非常有效。关于这个问题的任何想法:unless the view becomes too small, then the view should scroll。否则,这一切都可以在没有滚动视图的情况下完成。 @JamesWebster 您可以将 UIVIew 提供给 Scrollview BottomSpace,该值将在 30 左右。给出此约束的出口,然后如果 iphone 4s 则为 30,其他设备为 0。所以你的视图将在 4 秒内滚动。它只是一些设置。 我需要额外使用相交矩形来确定滚动视图应该扩展多少,但我认为我现在可以在任何屏幕尺寸下使用它。感谢您的帮助【参考方案2】:

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

创建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是一个不同的类,它是UIView的子类,它不包含在代码中,仅供参考。将您的视图替换为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中有多个子视图,那么使用底部视图(最后附加在scrollView中的子视图),用于constraint1constraint2变量。

【讨论】:

以上是关于我可以使用自动布局在 UIScrollView 中包含灵活空间吗?的主要内容,如果未能解决你的问题,请参考以下文章

通过 UIScrollView 使用代码中的自动布局

UIScrollView 不使用自动布局约束

使用自动布局在自定义 UITableViewCell 上分页 UIScrollView

UIScrollView SetContentSize 与自动布局

UIScrollView 不使用自动布局约束

包含动态 TableView 高度的 UIScrollView 的自动布局