You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何实现垂直标签栏?修正现有布局问题

问题解决:实现目标布局并修正旋转导致的布局错位

核心问题分析

直接通过transform旋转视图会破坏AutoLayout的布局逻辑——AutoLayout始终基于视图原始未旋转的尺寸计算约束,旋转后视图的实际显示尺寸与约束尺寸不匹配,最终导致布局错位。

推荐解决方案:避免视图旋转,直接调整布局结构

通过调整文字排版和StackView的排列方向,无需旋转即可实现目标布局,同时完全适配AutoLayout:

1. 修改左侧竖排Label的实现

不用旋转整个Label,而是让文字自然竖排:

let label2 = UILabel()
label2.text = "Label"
label2.backgroundColor = .red
label2.textColor = .white
label2.textAlignment = .center
label2.font = UIFont.systemFont(ofSize: 14)
// 将文字拆分为单个字符换行,实现竖排效果
label2.text = "Label".map { String($0) }.joined(separator: "\n")
label2.numberOfLines = 0
label2.translatesAutoresizingMaskIntoConstraints = false

2. 重构右侧彩色标签的StackView

直接使用垂直StackView排列彩色标签,无需旋转:

var buttonArray = [UILabel]()
for (myKey, myValue) in colorDictionary {
    buttonArray.append(colorButton(withColor: myValue, title: myKey))
}

// 改用垂直StackView,自然实现上下排列
let verticalStack = UIStackView(arrangedSubviews: buttonArray)
verticalStack.axis = .vertical
verticalStack.distribution = .fillEqually
verticalStack.alignment = .fill
verticalStack.spacing = 2 // 增加标签间的间距,匹配目标样式
verticalStack.translatesAutoresizingMaskIntoConstraints = false

3. 调整主StackView约束

let mainStackView = UIStackView(arrangedSubviews: [label2, verticalStack])
mainStackView.axis = .horizontal
mainStackView.spacing = 8 // 左右模块的间距
mainStackView.translatesAutoresizingMaskIntoConstraints = false
mainContainer.addSubview(mainStackView)

NSLayoutConstraint.activate([
    mainStackView.topAnchor.constraint(equalTo: mainContainer.topAnchor, constant: 5),
    mainStackView.leftAnchor.constraint(equalTo: mainContainer.leftAnchor, constant: 20),
    mainStackView.rightAnchor.constraint(equalTo: mainContainer.rightAnchor, constant: -20),
    mainStackView.bottomAnchor.constraint(equalTo: mainContainer.bottomAnchor, constant: -5),
    label2.widthAnchor.constraint(equalToConstant: 40) // 固定左侧标签宽度
])

4. 优化colorButton方法

func colorButton(withColor color: UIColor, title: String) -> UILabel{
    let newButton = UILabel()
    newButton.backgroundColor = color
    newButton.text = title
    newButton.textAlignment = .center
    newButton.textColor = .white
    newButton.font = UIFont.systemFont(ofSize: 14)
    newButton.numberOfLines = 1
    return newButton
}

备选方案:如果必须使用视图旋转

若你坚持要通过旋转实现,需要用容器视图包裹旋转后的元素,手动适配容器尺寸与旋转后视图的尺寸:

// 左侧Label的容器
let labelContainer = UIView()
labelContainer.translatesAutoresizingMaskIntoConstraints = false
let label2 = UILabel()
label2.text = "Label"
label2.backgroundColor = .red
label2.textColor = .white
label2.textAlignment = .center
label2.translatesAutoresizingMaskIntoConstraints = false
labelContainer.addSubview(label2)
label2.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)

// 让容器尺寸匹配旋转后的Label尺寸
NSLayoutConstraint.activate([
    label2.centerXAnchor.constraint(equalTo: labelContainer.centerXAnchor),
    label2.centerYAnchor.constraint(equalTo: labelContainer.centerYAnchor),
    labelContainer.widthAnchor.constraint(equalTo: label2.heightAnchor),
    labelContainer.heightAnchor.constraint(equalTo: label2.widthAnchor)
])

// 右侧Stack的容器
let stackContainer = UIView()
stackContainer.translatesAutoresizingMaskIntoConstraints = false
let horizontalStack = UIStackView(arrangedSubviews: buttonArray)
horizontalStack.axis = .horizontal
horizontalStack.distribution = .fillEqually
horizontalStack.alignment = .fill
horizontalStack.spacing = 2
horizontalStack.translatesAutoresizingMaskIntoConstraints = false
horizontalStack.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
stackContainer.addSubview(horizontalStack)

// 让容器尺寸匹配旋转后的Stack尺寸
NSLayoutConstraint.activate([
    horizontalStack.centerXAnchor.constraint(equalTo: stackContainer.centerXAnchor),
    horizontalStack.centerYAnchor.constraint(equalTo: stackContainer.centerYAnchor),
    stackContainer.widthAnchor.constraint(equalTo: horizontalStack.heightAnchor),
    stackContainer.heightAnchor.constraint(equalTo: horizontalStack.widthAnchor)
])

// 主Stack布局
let mainStackView = UIStackView(arrangedSubviews: [labelContainer, stackContainer])
mainStackView.axis = .horizontal
mainStackView.spacing = 8
mainStackView.translatesAutoresizingMaskIntoConstraints = false
mainContainer.addSubview(mainStackView)

NSLayoutConstraint.activate([
    mainStackView.topAnchor.constraint(equalTo: mainContainer.topAnchor, constant: 5),
    mainStackView.leftAnchor.constraint(equalTo: mainContainer.leftAnchor, constant: 20),
    mainStackView.rightAnchor.constraint(equalTo: mainContainer.rightAnchor, constant: -20),
    mainStackView.bottomAnchor.constraint(equalTo: mainContainer.bottomAnchor, constant: -5),
    labelContainer.widthAnchor.constraint(equalToConstant: 40)
])

内容的提问来源于stack exchange,提问作者Andrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 13:25:18