为啥 UIStackView 不堆叠 UILabel 安排的子视图?
Posted
技术标签:
【中文标题】为啥 UIStackView 不堆叠 UILabel 安排的子视图?【英文标题】:Why does UIStackView not stack a UILabel arrangedSubview?为什么 UIStackView 不堆叠 UILabel 安排的子视图? 【发布时间】:2018-03-30 19:45:18 【问题描述】:我有一个 UIStackView,作为排列的子视图,我有两个 UIView 和一个 UILabel。 UIView 一个接一个堆叠,而 UILabel 与子视图的前沿对齐。
代码:
let stack = UIStackView()
stack.axis = .horizontal
stack.distribution = .fillProportionally
stack.alignment = .center
stack.spacing = 7
view.addSubview(stack)
stack.translatesAutoresizingMaskIntoConstraints = false
stack.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
stack.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
let icon = UIView()
icon.backgroundColor = UIColor.red
stack.addArrangedSubview(icon)
icon.translatesAutoresizingMaskIntoConstraints = false
icon.heightAnchor.constraint(equalToConstant: 42).isActive = true
icon.widthAnchor.constraint(equalToConstant: 42).isActive = true
let icon2 = UIView()
icon2.backgroundColor = UIColor.red
stack.addArrangedSubview(icon2)
icon2.translatesAutoresizingMaskIntoConstraints = false
icon2.heightAnchor.constraint(equalToConstant: 42).isActive = true
icon2.widthAnchor.constraint(equalToConstant: 42).isActive = true
let label = UILabel()
label.lineBreakMode = .byWordWrapping
label.numberOfLines = 0
label.sizeToFit()
label.translatesAutoresizingMaskIntoConstraints = false
label.backgroundColor = .yellow
label.text = "Hello World! Again"
label.textColor = .black
stack.addArrangedSubview(label)
输出:
【问题讨论】:
多行标签没有固有宽度(嗯,确实有,但不是您尝试使用它的方式)。你必须以某种方式给它一个宽度,要么通过约束,要么通过约束其容器的宽度——在这种情况下,是堆栈视图的宽度。 【参考方案1】:为了清楚起见...
首先,不要使用.fillProportionally
。无论你认为这会做什么,它都是错误的。您已将两个“图标”明确设置为每个 42 点宽。如果堆栈视图使用.fillProportionally
,它将尝试更改这些视图的宽度,您将遇到自动布局冲突。
其次,UILabel
和 .numberOfLines = 0
必须有宽度。否则,没有办法知道在哪里打断文本......如果有很多文本,它会延伸到视图的两侧。
第三,label.sizeToFit()
行在这里不会完成任何事情。删掉就好了。
如果添加这一行:
stack.widthAnchor.constraint(equalToConstant: 200.0).isActive = true
然后堆栈视图将扩展到 200 点宽...
自动布局将使第一个排列视图的宽度为 42(因为这是您声明的宽度),第二个视图也是如此。由于您已将间距设置为7
,因此它将计算
42 + 7 + 42 + 7
等于98
。它从堆栈视图的宽度中减去它:
200 - 98 = 102
是它会给你的标签的宽度。
结果:
如果您不想将宽度显式设置为200
,则可以将其设置为父视图宽度的百分比,或为其设置前导和尾随约束。
【讨论】:
【参考方案2】:尝试将distribution
改为fill
stack.distribution = .fill
多行设置
评论后
【讨论】:
所以确实将它放入堆栈(耶),但它不尊重 uilabel 的固有大小,即它压扁它,使其与其他两个 UIView 的宽度相同,并且导致文本在几乎每个单词后中断。 让它拉伸评论 .lines ,或者给它一个宽度以上是关于为啥 UIStackView 不堆叠 UILabel 安排的子视图?的主要内容,如果未能解决你的问题,请参考以下文章
即使隐藏了排列的子视图,UIStackView 似乎也会堆叠间距