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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:26:13  来源:igfitidea点击:

Multiline label in UIStackView

iosuikituilabelxcode7uistackview

提问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

  1. Embed the UILabelinside a UIView(Editor -> Embed In -> View)
    1. Use constraints to fit the UILabelto the UIView(for example, trailing space, top space, and leading space to superview constraints)
  1. 嵌入UILabel里面一个UIView(编辑器 -> 嵌入 -> 查看)
    1. 使用约束以适合UILabelUIView(例如,后空间,顶部空间,并导致空间上海华约束)

The UIStackViewwill stretch out the UIViewto fit properly, and the UIViewwill constrain the UILabelto multiple lines.

UIStackView要伸出的UIView配合不当,而UIView将限制UILabel为多行。

回答by pbm

For a horizontal stack view that has a UILabelas 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 .fillis used the horizontal UIStackViewdoes 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 multiLineunless 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除非您给它一个固定的宽度,否则堆栈视图仍然不会增长。当我们固定它的宽度时,当达到该宽度时它会中断为多行,如下所示:

screen recording

屏幕录制

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

Just set number of lines to 0 in Attribute inspector for label. It will work for you.

只需在标签的属性检查器中将行数设置为 0。它会为你工作。

enter image description here

在此处输入图片说明

回答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 UIStackViewmade up of multiline UILabels with automatic height.

这是UIStackViewUILabel具有自动高度的 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)

enter image description here

在此处输入图片说明

##代码##

Here is a sample ViewControllerthat uses it.

这是一个ViewController使用它的示例。

##代码##

回答by Skoua

The magic trick for me was to set a widthAnchorto the UIStackView.

对我来说,魔术是将 a 设置widthAnchorUIStackView.

Setting leadingAnchorand trailingAnchorwon't work, but setting centerXAnchorand widthAnchormade the UILabel display correctly.

设置leadingAnchortrailingAnchor不起作用,但设置centerXAnchorwidthAnchor使 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 UILabelinside anything and has been tested with Xcode 9.2 and Swift 4. Hope it's helpful.

以下是多行标签的 Playground 实现,在UIStackView. 它不需要在UILabel内部嵌入任何东西,并且已经用 Xcode 9.2 和 Swift 4 进行了测试。希望它有帮助。

##代码##