iOS 布局约束:当内容到达底部时固定到底部或随内容流动

Posted

技术标签:

【中文标题】iOS 布局约束:当内容到达底部时固定到底部或随内容流动【英文标题】:iOS layout constraint: pin to bottom or flow with content when content reaches bottom 【发布时间】:2018-09-27 01:43:08 【问题描述】:

我有一个带有垂直堆栈视图的UIScrollView,它有一个标签和一个按钮,我希望按钮留在屏幕底部,并且一旦标签的文本增加并到达按钮,按钮就会停留在标签下方,它们一起滚动。

我在想:

let lableFit = self.label.systemLayoutSizeFitting(targetSize)
let buttonFit = self.button.systemLayoutSizeFitting(targetSize)

if labelFit.height + buttonFit.height > contentHeight 
    button.bottomAnchor.constrain(equalTo:scrollView.contentLayoutGuide.bottomAnchor)
 else 
    button.bottomAnchor.constrain(equalTo:scrollView.frameLayoutGuide.bottomAnchor)

这行得通吗?以及适合标签和按钮的目标尺寸应该是多少?

谢谢!

【问题讨论】:

【参考方案1】:

听起来你想要这个:

我们要这样设置:

我们需要配置堆栈视图以允许标签和按钮之间有可变数量的空白空间。我们可以通过将堆栈视图的“分布”设置为“等间距”来做到这一点。然后将堆栈视图的“间距”设置为标签和按钮之间所需的最小填充量。我在演示中将其设置为 12。

一旦我们有了视图层次结构,我们就需要创建适当的约束。让我们以不同的方式重申您的目标:我们希望堆栈视图(包含标签和按钮)至少与屏幕一样高。我们需要什么约束?

滚动视图总是需要在它的所有四个边缘和它的子视图之间进行约束,因为这些约束告诉滚动视图如何设置它的contentSize。在这种情况下,我们可以将滚动视图的四个边缘约束到堆栈视图的相应边缘。这些是屏幕截图中的“Stack View.xxx = xxx”和“xxx = Stack View.xxx”约束。

我们还需要告诉堆栈视图有多大。我们不能用堆栈视图和滚动视图之间的约束来做到这一点,因为这些只会影响滚动视图的contentSize。相反,我们将堆栈视图约束到根视图。

我们希望堆栈视图与屏幕一样宽,因此我们将堆栈视图的宽度限制为等于根视图安全区域的宽度。这是“Stack View.width = Safe Area.width”约束。

我们希望堆栈视图至少与屏幕一样高,但我们希望允许它更高,因此我们将堆栈视图的高度限制为大于或等于根视图安全区域的高度。这是“Stack View.height ≥ Safe Area.height”约束。

我们希望滚动视图填满屏幕,因此我们将其边缘限制在根视图安全区域的边缘。这些是屏幕截图中的“Safe Area.xxx = Scroll View.xxx”约束。

为确保标签适当地环绕其文本,请将标签的宽度限制为等于堆栈视图的宽度。这是屏幕截图中的“Label.width = width”约束。

您还应该如下设置标签和按钮的内容大小优先级:

Content Hugging Priority
    Horizontal: 800
    Vertical: 800
Content Compression Resistance Priority
    Horizontal: 1000
    Vertical: 1000

这将确保标签和按钮都不会被不当拉伸或挤压。

为了演示,我将我的故事板连接到这个视图控制器:

import UIKit

class ViewController: UIViewController 

    @IBOutlet var label: UILabel!
    @IBOutlet var scrollView: UIScrollView!

    @IBAction func buttonWasTapped() 
        label.text = (label.text ?? "") + "\n\nhere is\nmore text\nfor demo\npurposes"
        scrollView.layoutIfNeeded()
        scrollView.scrollRectToVisible(CGRect(x: 0, y: scrollView.contentSize.height - 1, width: 1, height: 1), animated: true)
    


【讨论】:

非常感谢!我希望有多个绿色勾号。你的回答不仅告诉了我如何实现,还让我学习了你的思维方式,对以后解决问题很有帮助!

以上是关于iOS 布局约束:当内容到达底部时固定到底部或随内容流动的主要内容,如果未能解决你的问题,请参考以下文章

滚动视图内的Android约束布局高度无效

iOS 8 Xcode 6:使用顶部/底部布局指南进行顶部/底部约束时,应用程序始终崩溃

iOS 8 自动布局 - 动态调整 4 个方形视图的大小

uiscrollview无法滚动到底部

自动布局和约束问题

iOS自动布局未在底部固定空间显示按钮