如何为 UILabel 指定一个约束以保持在 UISegmentedControl 的每个段下方居中?
Posted
技术标签:
【中文标题】如何为 UILabel 指定一个约束以保持在 UISegmentedControl 的每个段下方居中?【英文标题】:How to specify a constraint for a UILabel to remain centered beneath each segment of a UISegmentedControl? 【发布时间】:2015-04-14 21:00:00 【问题描述】:在我的 ios 8 应用程序中,我有一个 UISegmentedControl 可以拉伸以适应设备屏幕的宽度。因此,在 iPad 上,它的像素宽度比 iPhone 6+ 上的多,而 iPhone 6+ 上的像素宽度比 iPhone 6 多,等等。
在 UISegmentedControl 的每个段下方居中,我有一个 UILabel。所以有5个段和5个UILabel。每个 UILabel 都有一个固定的宽度(由约束固定)。但是,如果显示尺寸增加,它们就会变得不居中。
如何在 Interface Builder 中指定强制每个 UILabel 在每个段下方居中的约束?如果我能让元素随着显示尺寸的缩放而保持成比例的间距,我会很高兴,但我也不知道该怎么做。
我似乎所能做的就是通过在中间段和 UISegmentedControl 之间指定一个 Center X Alignment 来将中间 UILabel 直接居中在中间段下方。
我在所有 UILabel 之间以及外部 UILabel 和视图边缘之间指定了一个水平空间约束,并将所有这些设置为“大于或等于”。它们都具有相同的优先级,但奇怪的是,它们并非都彼此成比例。
由此产生的问题是每个 UILabel 之间的水平空间量不会随着设备屏幕宽度的增加而平滑缩放。如果我将所有内容对齐到正确的位置iPhone 5S 的屏幕宽度,然后在 iPad 上,它们的对齐方式都很不稳定,只有中间一个与它的部分对齐。其余的都偏离中心。
似乎没有办法将整体显示宽度的百分比指定为约束——您只能以像素为单位进行指定。 真的吗?!? !
显然,我可以使对象的 宽度 变得灵活,但是因为它们是带有右对齐文本的文本标签,所以一切都搞砸了。
当然我在这里遗漏了一些东西......因为自动布局的目的是让你的界面根据屏幕大小进行缩放,当然有一种方法可以指定一个约束作为任何给定视图或子视图的百分比...肯定!!!但是怎么做?我已经阅读了文档,但我终其一生都无法弄清楚。
顺便说一句,我确实看到过去人们使用过像spacer views 或multiple sets of constraints 这样的粗略黑客,但这些肯定是过时的答案,我只是忽略了一些非常明显的东西...... 对?
【问题讨论】:
您的分段控制器的所有段是否都相同大小?顺便说一句,没有以像素为单位指定,它以点为单位指定。此外,使用间隔视图没有什么不好的,它是均匀分布视图的最简单方法,但我认为你不需要这样做。为什么不能将文本居中对齐,并为标签提供灵活的宽度和相同的大小? 关于“像素”与“点”(双关语)的观点。分段控制器的所有分段宽度相同。我必须为各个 UILabel 使用固定宽度,以便它们与视图背景中的某些图形对齐。由于 UISegmentedControl 的每个段下方的 UI 标签堆栈内发生小数点对齐问题以及图形对齐问题,我无法提供文本中心对齐。我可以使用空白的间隔视图,但这看起来很笨拙……肯定有灵活的空间吗? 不,没有灵活的空间(那会很好)。如果没有更多详细信息,很难理解标签中您要与分段控件的标题对齐的确切内容。除非您将它们居中对齐,或者它们都具有相同长度的文本,否则我认为它们看起来不会对齐。您正在尝试做的事情的图片会很有帮助。 只考虑UILabels的边界框。每个 UILabel 的边界框的左右两边应与 UISegmentedControl 中其上方的段的左右边界等距。不用担心 UILabel 中的实际文本。只是边界框! 【参考方案1】:您可以通过使标签的 centerX 约束等于 superview.trailing 乘以 0.1、0.3、0.5、0.7 和 0.9 来实现此目的,常量为 0。要创建这些约束,请将 5 个标签添加到视图中。给最左边一个分段控件的垂直间距约束。选择所有 5 个标签并给它们一个“垂直中心”对齐约束。现在按住 control 从每个标签拖动到屏幕右侧,然后选择“Trailing space to container margin”约束。编辑这些尾随约束中的每一个,使其看起来像这样(除了需要给定我上面提到的值的乘数):
你必须颠倒第一个和第二个项目(你从第一个项目上的下拉),将 Label.trailing 更改为 Label.Center X,并取消选中“相对于边距”框,然后更正常数和乘数值。
这种方法只有在分段控件一直延伸到整个屏幕且边缘没有填充时才有效。如果要填充边缘,则需要使用完全不同的方法。您需要在分段控件下方创建 5 个 UIView——将最左侧的左边缘与分段控件的左边缘对齐。将最右边的右边缘与分段控件的右边缘对齐。为 5 个视图提供相等的宽度和 0 长度的水平间距约束,从每个视图到其邻居。这将为您提供 5 个在宽度上模拟分段控件的视图,每个视图的宽度与其中一个段的宽度相同(假设所有段的宽度相同——如果不是这样,你就完蛋了)。然后你只需要添加你的标签作为这 5 个视图的子视图,并给它们 centerX 和 centerY 约束。
【讨论】:
以上是关于如何为 UILabel 指定一个约束以保持在 UISegmentedControl 的每个段下方居中?的主要内容,如果未能解决你的问题,请参考以下文章
向其子视图(即 UILabel)添加约束时,无法保持集合视图单元格的固定大小