使用自动布局在 UIScrollView 中将可变宽度的文本列居中
Posted
技术标签:
【中文标题】使用自动布局在 UIScrollView 中将可变宽度的文本列居中【英文标题】:Centering a variable width column of text in a UIScrollView using Auto Layout 【发布时间】:2016-03-13 22:47:49 【问题描述】:我有一个看似简单的设计,但我无法使用自动布局约束来表达:在 UIScrollView 中,我需要显示一个居中的文本列,其最小宽度为 300 pts,最大宽度为 500 pts(保持在所有情况下至少留出 10 分的边距。)
文本列实际上是一个 UIStackView,但这对于本次讨论并不重要,该视图也可以很容易地成为具有宽高比的 UIImageView。
我尝试使用具有不同内容拥抱和压缩阻力的填充视图、具有水平轴的堆栈视图、具有小于或等于常量的宽度约束等。我想在情节提要中完成所有这些,在布局更改期间嗅探或使用大小类感觉就像在作弊。
(我的一些实验导致 Xcode 在更新情节提要时挂起:给我一个痛苦的提示,即这些约束没有解决方案。)
在您提出建议之前,I have read about the subtleties of UIScrollView and Auto Layout。
这似乎是一个无法解决的问题,这是一种耻辱。这是一种非常常见的模式,设计师喜欢在 CSS 中使用(使用 min-width 和 max-width)。我希望我在这里遗漏了一些东西,并且对自动布局有更深入了解的人可以解释一种方法来做到这一点(并作为其他想要做同样事情的人的参考。)
更新: 下面 Adam 和 Ben 的建议对于实现这种布局非常有帮助。但是,一旦您获得多个文本块,自动布局迭代求解器就无法处理它(并且 Xcode 挂起。)有关更多信息:http://openradar.appspot.com/25173433
【问题讨论】:
Erica Sadun 在她的 AutoLayout 书中有一个 UIScrollView 子类,这可能会有所帮助。她可能具有您正在寻找的 AutoLayout 知识。 【参考方案1】:这个其实很简单!我已将storyboard file 包含在演示中。内容视图中文本的关键位:
领先/落后边距 >= 10 宽度 >= 300 宽度 居中对齐不需要更改优先级,除非您有其他要优先的内容。
【讨论】:
感谢您的样品,本。不幸的是,它并没有解决我的问题,但它确实帮助我编写了一个雷达,显示一旦布局变得更加复杂,Xcode 就会被破坏。 openradar.appspot.com/25173433 很高兴它能让你走得更远!我检查了雷达中的故事板。我以前见过这种行为,你可以责怪堆栈视图彼此相关。通过分配相同的设置( 消除堆栈视图等宽约束的问题在于,关心标签的宽度会导致堆栈宽度发生变化:由此产生的参差不齐的边缘看起来很糟糕。理论上,应该可以将标签移出堆栈视图并给它们明确的约束(而不是依赖于自动的)。再次感谢您的帮助! 不确定这是否有帮助(因此在评论中),但只有这 4 个约束仍然是模棱两可的。宽度可以在 300 到 500 之间,并且没有任何东西可以帮助系统确定它。如果添加以下约束会怎样:宽度 = 500,优先级 999?这样,文本视图将尽可能宽 500。【参考方案2】:尝试 10 的前导和尾随约束,但将它们的优先级设置为 750。然后水平居中,宽度 >= 300 和
【讨论】:
【参考方案3】:如果我正确地解决了这个问题,我想我有一个相当简单的设置可以解决这个问题。
我从滚动视图开始,然后添加一个基本的 UIView 作为容器。我将 UIView 固定到滚动视图的顶部、底部、前导和后沿,以便正确管理滚动视图的内容大小。我向该容器视图添加了一个约束,以匹配滚动视图的宽度。
然后我将 UIStackView 添加到容器视图中,并给它以下约束:
将中心 X 与 Superview 对齐 到 Superview 的尾随空格 >= 10 领先空间到 Superview >= 10 宽度 = 500,优先级 750 宽度 >= 300 到 Superview 的底部空间 = 10 到 Superview 的顶部空间 = 10除宽度 = 500 外,所有的都具有默认优先级。然后我在堆栈视图中放置了一些标签,我得到的结果是一个列,其两边至少有 10 点的边距,但永远不会超过 500点,根据堆栈视图的内容,宽度将下降到 300 点。
【讨论】:
【参考方案4】:如果我正确理解问题,我想我有一个解决方案。我在 UIScrollView 中使用 UILabel 对此进行了测试,但它应该适用于任何具有固有大小的视图。对于您使用的任何内部视图,请尝试以下约束:
宽度 宽度 >= 300 将中心 X 与 Superview 对齐 到 Superview 的顶部空间 = 10 Superview 的底部空间 = 10 Superview 的前导空间 = 10(优先级 750) Superview 的尾随空格 = 10(优先级 750) 横向内容抗压优先级:250为水平内容压缩阻力设置低优先级是关键。我的 UILabel 里面有一堆文本,所以它的内在内容大小大约是 2200 像素。使用默认的水平压缩阻力,它将始终扩展到 500 像素的最大宽度,并且滚动视图将在较小的屏幕上水平和垂直滚动。我只想要垂直滚动,所以我在 UILabel 上设置了较低的水平压缩阻力优先级,这会告诉自动布局挤压它以适应。
【讨论】:
以上是关于使用自动布局在 UIScrollView 中将可变宽度的文本列居中的主要内容,如果未能解决你的问题,请参考以下文章
使用自动布局在自定义 UITableViewCell 上分页 UIScrollView
UIScrollView SetContentSize 与自动布局