ios UIStackView 中的多行标签
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34386528/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multiline label in UIStackView
提问by Boon
When putting multiline label (with linebreak set to Word Wrap) into a stack view, the label immediately loses the linebreak and displays the label text in one line instead.
将多行标签(将换行符设置为 Word Wrap)放入堆栈视图时,标签会立即丢失换行符并在一行中显示标签文本。
Why is this happening and how does one preserve multiline label within a stack view?
为什么会发生这种情况以及如何在堆栈视图中保留多行标签?
回答by Andy
The correct answer is here: https://stackoverflow.com/a/43110590/566360
正确答案在这里:https: //stackoverflow.com/a/43110590/566360
- Embed the
UILabel
inside aUIView
(Editor -> Embed In -> View)- Use constraints to fit the
UILabel
to theUIView
(for example, trailing space, top space, and leading space to superview constraints)
- Use constraints to fit the
- 嵌入
UILabel
里面一个UIView
(编辑器 -> 嵌入 -> 查看)- 使用约束以适合
UILabel
于UIView
(例如,后空间,顶部空间,并导致空间上海华约束)
- 使用约束以适合
The UIStackView
will stretch out the UIView
to fit properly, and the UIView
will constrain the UILabel
to multiple lines.
将UIStackView
要伸出的UIView
配合不当,而UIView
将限制UILabel
为多行。
回答by pbm
For a horizontal stack view that has a UILabel
as one of its views, in Interface Builder firstly set label.numberOfLines = 0
. This should allow the label to have more than 1 line. This initially failed to work for me when the stack view had stackView.alignment = .fill
. To make it work simply set stackView.alignment = .center
. The label can now expand to multiple lines within the UIStackView
.
对于将 aUILabel
作为其视图之一的水平堆栈视图,首先在 Interface Builder 中设置label.numberOfLines = 0
. 这应该允许标签有超过 1 行。当堆栈视图具有stackView.alignment = .fill
. 要使其工作,只需设置stackView.alignment = .center
. 标签现在可以扩展为UIStackView
.
The Apple documentationsays
在苹果的文档说
For all alignments except the fill alignment, the stack view uses each arranged view's intrinsic?Content?Size property when calculating its size perpendicular to the stack's axis
对于除填充对齐之外的所有对齐方式,堆栈视图在计算垂直于堆栈轴的大小时使用每个排列视图的固有?Content?Size 属性
Note the word excepthere. When .fill
is used the horizontal UIStackView
does NOT resize itself vertically using the arranged subviews sizes.
注意这个词,除了这里。当.fill
使用横向UIStackView
不调整大小本身垂直使用布置子视图的尺寸。
回答by Irfan
- First set the label number of lines to 0
- The stack view still won't grow to
multiLine
unless you give it a fixed width. When we fix its width then it break to multiline when that width is reached as shown:
- 首先将标签行数设置为0
multiLine
除非您给它一个固定的宽度,否则堆栈视图仍然不会增长。当我们固定它的宽度时,当达到该宽度时它会中断为多行,如下所示:
If we don't give a fixed width to the stack view then things get ambiguous. How long will the stack view grow with the label (if the label value is dynamic)?
如果我们不给堆栈视图一个固定的宽度,那么事情就会变得模棱两可。堆栈视图会随着标签增长多长时间(如果标签值是动态的)?
Hope this can fix your issue.
希望这可以解决您的问题。
回答by Pablo Martinez
Setting preferredMaxLayoutWidth to the UILabel worked for me
将 preferredMaxLayoutWidth 设置为 UILabel 对我有用
self.myLabel.preferredMaxLayoutWidth = self.bounds.size.width;
回答by technerd
回答by Bill Chan
After trying all above suggestion I found no properties change is need for the UIStackView. I just change the properties of the UILabels as following (The labels are added to a vertical stack view already):
在尝试了以上所有建议后,我发现 UIStackView 不需要更改属性。我只是按如下方式更改 UILabels 的属性(标签已添加到垂直堆栈视图中):
Swift 4 example:
斯威夫特 4 示例:
[titleLabel, subtitleLabel].forEach(){
// A vertical stackview with multiline labels and automatic height.
class ThreeLabelStackView: UIStackView {
let label1 = UILabel()
let label2 = UILabel()
let label3 = UILabel()
init() {
super.init(frame: .zero)
self.translatesAutoresizingMaskIntoConstraints = false
self.axis = .vertical
self.distribution = .fill
self.alignment = .fill
label1.numberOfLines = 0
label2.numberOfLines = 0
label3.numberOfLines = 0
label1.lineBreakMode = .byWordWrapping
label2.lineBreakMode = .byWordWrapping
label3.lineBreakMode = .byWordWrapping
self.addArrangedSubview(label1)
self.addArrangedSubview(label2)
self.addArrangedSubview(label3)
// (Add some test data, a little spacing, and the background color
// make the labels easier to see visually.)
self.spacing = 1
label1.backgroundColor = .orange
label2.backgroundColor = .orange
label3.backgroundColor = .orange
label1.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi."
label2.text = "Hello darkness my old friend..."
label3.text = "When I wrote the following pages, or rather the bulk of them, I lived alone, in the woods, a mile from any neighbor, in a house which I had built myself, on the shore of Walden Pond, in Concord, Massachusetts, and earned my living by the labor of my hands only."
}
required init(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
.numberOfLines = 0
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let myLabelStackView = ThreeLabelStackView()
self.view.addSubview(myLabelStackView)
// Set stackview width to its superview.
let widthConstraint = NSLayoutConstraint(item: myLabelStackView, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.view, attribute: NSLayoutConstraint.Attribute.width, multiplier: 1, constant: 0)
self.view.addConstraints([widthConstraint])
}
}
.lineBreakMode = .byWordWrapping
import UIKit
import PlaygroundSupport
let containerView = UIView()
containerView.frame = CGRect.init(x: 0, y: 0, width: 400, height: 500)
containerView.backgroundColor = UIColor.white
var label = UILabel.init()
label.textColor = .black
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "This is an example of sample text that goes on for a long time. This is an example of sample text that goes on for a long time."
let stackView = UIStackView.init(arrangedSubviews: [label])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.distribution = .fill
stackView.alignment = .fill
containerView.addSubview(stackView)
stackView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
stackView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
stackView.widthAnchor.constraint(equalTo: containerView.widthAnchor).isActive = true
stackView.heightAnchor.constraint(equalTo: containerView.heightAnchor).isActive = true
PlaygroundPage.current.liveView = containerView
.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)
}
回答by zekel
Here's a full example of a vertical UIStackView
made up of multiline UILabel
s with automatic height.
这是UIStackView
由UILabel
具有自动高度的 multiline 组成的垂直的完整示例。
The labels wrap based on the stackview's width and the stackview's height is based on the label's wrapped height. (With this approach you don't need to embed the labels in a UIView
.) (Swift 5, iOS 12.2)
标签基于 stackview 的宽度环绕,stackview 的高度基于标签的环绕高度。(使用这种方法,您无需将标签嵌入UIView
.)(Swift 5,iOS 12.2)
Here is a sample ViewController
that uses it.
这是一个ViewController
使用它的示例。
回答by Skoua
The magic trick for me was to set a widthAnchor
to the UIStackView
.
对我来说,魔术是将 a 设置widthAnchor
为UIStackView
.
Setting leadingAnchor
and trailingAnchor
won't work, but setting centerXAnchor
and widthAnchor
made the UILabel display correctly.
设置leadingAnchor
和trailingAnchor
不起作用,但设置centerXAnchor
和widthAnchor
使 UILabel 正确显示。
回答by aumansoftware
iOS 9+
iOS 9+
Call [textLabel sizeToFit]
after setting the UILabel's text.
[textLabel sizeToFit]
设置 UILabel 的文本后调用。
sizeToFit will re-layout the multiline label using preferredMaxWidth. The label will resize the stackView, which will resize the cell. No additional constraints besides pinning the stack view to the content view are required.
sizeToFit 将使用 preferredMaxWidth 重新布局多行标签。标签将调整 stackView 的大小,这将调整单元格的大小。除了将堆栈视图固定到内容视图之外,不需要其他约束。
回答by JaredH
The following is a Playground implementation of multi-line label with a line break inside a UIStackView
. It doesn't require embedding the UILabel
inside anything and has been tested with Xcode 9.2 and Swift 4. Hope it's helpful.
以下是多行标签的 Playground 实现,在UIStackView
. 它不需要在UILabel
内部嵌入任何东西,并且已经用 Xcode 9.2 和 Swift 4 进行了测试。希望它有帮助。