Xcode中标签行的Autoresizing布局出现异常结果
嘿,我来帮你搞定这个Autoresizing布局的问题!首先得给你提个醒:AutoresizingMask只能基于父视图来定义尺寸和位置的变化,没办法直接让一个标签的边缘跟着另一个兄弟标签走——这可能就是你觉得设置了约束但没达到预期的原因。
针对你的需求,我给你两种解决方案:一种是用嵌套容器配合Autoresizing实现,另一种是更灵活的AutoLayout方案(毕竟这种涉及兄弟视图依赖的布局,AutoLayout会更省心)。
方案1:Autoresizing + 嵌套容器
我们把布局拆成几个容器,每个容器负责一组标签,这样就能用Autoresizing来控制各组的尺寸:
父容器(整个行的容器)
- Frame: 和你要的行尺寸一致,比如
CGRectMake(0, 0, self.view.bounds.size.width, 44) - AutoresizingMask:
UIViewAutoresizingFlexibleWidth,确保它随父视图宽度变化
- Frame: 和你要的行尺寸一致,比如
左侧容器(包含Lat:和55.000)
Frame:
CGRectMake(0, 0, parentContainer.bounds.size.width/2, parentContainer.bounds.size.height)AutoresizingMask:
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight这个容器负责左半部分,宽度会随父容器自动调整到一半
Lat:标签
- 固定宽度,比如
CGFloat fixedWidth = 40 - Frame:
CGRectMake(0, 0, fixedWidth, leftContainer.bounds.size.height) - AutoresizingMask:
UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin,保持左对齐、固定宽度,高度随容器变化
- 固定宽度,比如
55.000标签
- Frame:
CGRectMake(fixedWidth, 0, leftContainer.bounds.size.width - fixedWidth, leftContainer.bounds.size.height) - AutoresizingMask:
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight,填充Lat:标签右侧到容器右边缘的空间
- Frame:
右侧容器(包含Lon:和-95.000)
Frame:
CGRectMake(parentContainer.bounds.size.width/2, 0, parentContainer.bounds.size.width/2, parentContainer.bounds.size.height)AutoresizingMask:
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight,负责右半部分,宽度自动调整到一半Lon:标签
- 固定宽度
fixedWidth = 40 - Frame:
CGRectMake((rightContainer.bounds.size.width - fixedWidth)/2, 0, fixedWidth, rightContainer.bounds.size.height),初始居中 - AutoresizingMask:
UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight,保持水平居中,高度随容器变化
- 固定宽度
-95.000标签
- Frame:
CGRectMake((rightContainer.bounds.size.width + fixedWidth)/2, 0, rightContainer.bounds.size.width/2 - fixedWidth/2, rightContainer.bounds.size.height) - AutoresizingMask:
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin,填充Lon:标签右侧到容器右边缘的空间
- Frame:
另外,你提到的“第一个标签占满整个宽度”,如果是指一个背景标签,直接把它放在父容器最底层,Frame和父容器一致,AutoresizingMask设为UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight就行,其他标签叠加在它上面。
方案2:AutoLayout(更推荐)
如果你的项目支持AutoLayout,用它来实现会更直观,不需要嵌套容器:
假设我们有fullWidthLabel(占满整个行宽度)、latLabel、latValueLabel、lonLabel、lonValueLabel这几个标签,添加以下约束:
fullWidthLabel
- 顶部、底部、左、右边缘和父视图对齐(占满整个宽度和高度)
latLabel
- 左边缘和父视图左对齐,顶部、底部和父视图对齐
- 设置固定宽度约束(比如40)
latValueLabel
- 左边缘和latLabel右对齐,顶部、底部和父视图对齐
- 右边缘和lonLabel左对齐
lonLabel
- 中心X和父视图中心X对齐,顶部、底部和父视图对齐
- 设置固定宽度约束(比如40)
lonValueLabel
- 左边缘和lonLabel右对齐,顶部、底部和父视图对齐
- 右边缘和父视图右对齐
这样设置后,latValueLabel会自动填充latLabel和lonLabel之间的空间,lonValueLabel填充lonLabel到父视图右边缘的空间,完全符合你的需求。
为什么你之前的Autoresizing设置没生效?
因为你可能试图让latValueLabel的左边缘跟着latLabel走,但Autoresizing做不到这一点——它只能让视图相对于父视图的边缘或尺寸变化,没办法关联兄弟视图的位置。嵌套容器的思路是把相关的视图放在同一个父容器里,这样容器的Autoresizing就能控制子视图的可用空间。
内容的提问来源于stack exchange,提问作者Guy Fisher

