web-dev-qa-db-ja.com

UIStackViewの複数行ラベル

複数行のラベル(改行をワードラップに設定)をスタックビューに配置すると、ラベルはすぐに改行を失い、代わりにラベルテキストを1行で表示します。

なぜこれが起こり、スタックビュー内で複数行ラベルをどのように保持するのですか?

104
Boon

正解はこちら: https://stackoverflow.com/a/43110590/56636

  1. UILabelUIView内に埋め込みます(エディター->埋め込み->表示)
    1. 制約を使用して、UILabelUIViewに合わせます(たとえば、末尾のスペース、上部のスペース、およびスーパービューの制約の先頭のスペース)。

UIStackViewは適切に収まるようにUIViewを伸ばし、UIViewUILabelを複数行に制限します。

147
Andy

ビューの1つとしてUILabelを持つ水平スタックビューの場合、Interface Builderで最初にlabel.numberOfLines = 0を設定します。これにより、ラベルに複数の行を含めることができます。スタックビューにstackView.alignment = .fillが含まれていた場合、これは最初は機能しませんでした。動作させるには、単にstackView.alignment = .centerを設定します。これで、ラベルはUIStackView内で複数行に展開できます。

Appleドキュメント

塗りつぶし配置を除くすべての配置について、スタックビューは、スタックの軸に垂直なサイズを計算するときに、配置された各ビューの組み込みのContentSizeプロパティを使用します

ここでWordexceptに注意してください。 .fillを使用すると、水平のUIStackViewは、配置されたサブビューのサイズを使用して、垂直方向にサイズを変更しません。

72
pbm
  • 最初に行のラベル番号を0に設定します
  • スタックビューは、固定幅を指定しない限り、multiLineに成長しません。幅を修正すると、次に示すように幅に達すると複数行に分割されます。

screen recording

スタックビューに固定幅を与えないと、あいまいになります。ラベルとともにスタックビューが成長する期間(ラベル値が動的な場合)

これで問題が解決することを願っています。

40
Irfan

ラベルの属性インスペクターで行数を0に設定するだけです。それはあなたのために働くでしょう。

enter image description here

11
technerd

PreferredMaxLayoutWidthをUILabelに設定するとうまくいきました

self.myLabel.preferredMaxLayoutWidth = self.bounds.size.width;
7
Pablo Martinez

iOS 9以降

UILabelのテキストを設定した後、[textLabel sizeToFit]を呼び出します。

sizeToFitは、preferredMaxWidthを使用して複数行ラベルを再レイアウトします。ラベルはstackViewのサイズを変更し、セルのサイズを変更します。スタックビューをコンテンツビューに固定する以外の追加の制約は必要ありません。

3
aumansoftware

以下は、UIStackView内に改行がある複数行ラベルのPlayground実装です。 UILabelを何かの中に埋め込む必要はなく、Xcode 9.2およびSwift 4.でテストされています。役に立てば幸いです。

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
3
JaredH

自動高さの複数行UIStackViewsで構成される垂直UILabelの完全な例を次に示します。

ラベルは、スタックビューの幅に基づいて折り返され、スタックビューの高さは、ラベルの折り返された高さに基づきます。 (このアプローチでは、ラベルをUIViewに埋め込む必要はありません。)(Swift 5、iOS 12.2)

enter image description here

// 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") }
}

以下は、それを使用するViewControllerのサンプルです。

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])
    }
}
2
zekel

私にとっての魔法は、widthAnchorUIStackViewに設定することでした。

leadingAnchorおよびtrailingAnchorを設定しても機能しませんが、centerXAnchorおよびwidthAnchorを設定すると、UILabelが正しく表示されます。

2
Skoua

UIStackViewプロパティを追加し、

stackView.alignment = .fill
stackView.distribution = .fillProportionally
stackView.spacing = 8.0
stackView.axis = .horizontal

UIView内にラベルを追加するのではなく、UITableViewCell内で使用している場合は、ローテーション時にデータをリロードしてください。

2
Sagar Daundkar

上記のすべての提案を試した後、UIStackViewのプロパティを変更する必要がないことがわかりました。 UILabelsのプロパティを次のように変更するだけです(ラベルは既に垂直スタックビューに追加されています)。

Swift 4の例:

    [titleLabel, subtitleLabel].forEach(){
        $0.numberOfLines = 0
        $0.lineBreakMode = .byWordWrapping
        $0.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)
    }
1
Bill Chan

システムレイアウトは、サブビューを描画するために、Origin、幅、高さを把握する必要があります。この場合、すべてのサブビューは同じ優先順位を持ち、その点で競合が発生します。

スタックサブビューの圧縮を設定すると、スタックビューが水平か垂直か、どの行を複数行にするかに応じて、複数行の問題を解決できます。 stackOtherSubviews .setContentCompressionResistancePriority(.defaultHight, for: .horizontal)lblTitle.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)

1
Trung Phan

@ Andy's Answerとほぼ同じですが、UILabelを追加のUIStackviewに追加できます。

私の場合、以前の提案に従いましたが、テキストは横向きだけでしたが、まだ1行に切り捨てられていました。ラベルのテキストに、目に見えない\0 null文字が原因であることがわかりました。それは私が挿入したemダッシュ記号と一緒に導入されたに違いありません。これがケースでも発生しているかどうかを確認するには、View Debuggerを使用してラベルを選択し、そのテキストを調べます。

0
Jordan H

私のために働いたもの!

stackview:配置:塗りつぶし、分布:塗りつぶし、superviewへの比例幅の制限ex。 0.8、

ラベル:中央、ライン= 0

0
Michał Ziobro

Xcode 9.2:

行数を0に設定するだけです。これを設定すると、ストーリーボードは奇妙に見えます。プロジェクトを実行する心配はありません。実行中は、ストーリーボードのセットアップに応じてすべてのサイズが変更されます。ストーリーボードにある種のバグだと思います。 enter image description here

ヒント:最後に「ライナーの数を0に設定」します。他のビューを編集する場合はリセットし、編集後に0に設定します。

enter image description here

0
Surendra Kumar

まだそれを機能させることができない人のために。そのUILabelの最小フォントスケールで自動縮小を設定してみてください。

スクリーンショットUILabel自動圧縮設定

0
Michal Mondík