如何实现两个Label并排:一个可自适应宽度,一个固定不被挤出?
嘿,这个布局问题我太熟悉了!之前做电商列表页的时候刚好碰到过类似的需求,给你两个实用的解决思路,看哪种更适合你的场景:
方案一:用AutoLayout自动处理(首推,不用手动计算)
这种方式不用写任何判断逻辑,靠布局优先级就能让系统自动帮你搞定:
- 给Label-B设置更高的内容 hugging priority(比如Label-A设为250,Label-B设为251),让布局引擎优先保证Label-B的固有宽度不被压缩
- 给Label-B设置更高的内容 compression resistance priority(比如Label-A设为749,Label-B设为750),防止Label-B被挤压变形
- 给Label-A开启尾部截断:
labelA.lineBreakMode = .byTruncatingTail - 最后给两个Label所在的容器View,添加trailing约束到父视图的trailing edge(比如留16px间距),别让Label-B的trailing悬空
这样设置后,不管Label-A的文本多长,Label-B都会稳稳留在屏幕内,Label-A会自动截断并显示“...”,完美适配各种屏幕尺寸和旋转场景。
方案二:赋值前手动计算文本宽度(满足你提前判断的需求)
如果你一定要在给Label-A赋值前就判断是否需要截断,可以通过计算文本宽度来实现:
- 先算出Label-B的固有宽度:因为文本固定6个字符,直接用
labelB.intrinsicContentSize.width就能拿到准确值 - 计算Label-A能使用的最大宽度:父视图宽度 - Label-A到leading的间距 - A和B的间距(10px) - Label-B的宽度 - Label-B到trailing的间距
- 计算要赋值的文本在Label-A字体下的实际宽度
- 如果文本宽度超过最大可用宽度,就调用系统方法截断并添加省略号
给你一段Swift代码示例:
// 确保在视图布局完成后计算,比如放在viewDidLayoutSubviews里 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() let leftMargin: CGFloat = 16 // Label-A到父视图leading的间距 let rightMargin: CGFloat = 16 // Label-B到父视图trailing的间距 let abSpacing: CGFloat = 10 // A和B的间距 // 拿到Label-B的固有宽度 let bWidth = labelB.intrinsicContentSize.width // 计算Label-A的最大可用宽度 let maxAWidth = parentView.bounds.width - leftMargin - abSpacing - bWidth - rightMargin let targetText = "这是一段超长的测试文本,用来模拟Label-A的可变内容情况" // 计算文本在Label-A字体下的宽度 let textWidth = NSString(string: targetText).boundingRect( with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: labelA.font.lineHeight), options: .usesLineFragmentOrigin, attributes: [.font: labelA.font], context: nil ).width if textWidth > maxAWidth { // 用系统方法自动截断并添加省略号,比手动截断更准确 let attributedText = NSAttributedString(string: targetText, attributes: [.font: labelA.font]) let truncatedText = attributedText.truncatingAttributedString(with: .byTruncatingTail, width: maxAWidth) labelA.attributedText = truncatedText } else { labelA.text = targetText } }
小提醒:
- 优先用方案一,AutoLayout的方案会自动处理所有边界情况(比如屏幕旋转、不同设备尺寸),比手动计算省心太多
- 如果用方案二,一定要在视图布局完成后计算宽度(比如
viewDidLayoutSubviews),不然父视图的宽度可能还没确定,计算出来的结果会不准
内容的提问来源于stack exchange,提问作者SKT
相关产品推荐
相关产品推荐

