UIStackViewの複数行ラベル


154

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

なぜこれが発生し、スタックビュー内でマルチラインラベルをどのように保持するのですか?


1
行数を0に設定しましたか?
dasdom

答えは見つかりましたか?
ブレンデン

回答:


204

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


  1. UILabel内部に埋め込むUIView(エディタ->埋め込み->表示)
  2. 制約を使用してに合わせます(たとえば、制約を監視するUILabelためのUIViewトレーリングスペース、トップスペース、リーディングスペース)。

UIStackView伸ばしますUIView適切にフィットし、かつUIView制約されますUILabel複数行に。


36
それはとても愚かですが、うまくいきます!ありがとう !たぶんある日、AppleはSDKで半分壊れていない何かをリリースする...
Guillaume L.

1
ちょっと、あなた!あなたは救世主です!私は何時間もそれをしていました:)属性インスペクターで行を0に設定することを忘れないでください、それだけがありませんでした。
17

8
これは回避策であり、正しい解決策はここにありますstackoverflow.com/a/43110590/566360
vietstone

2
水平方向の配置を中央に変更するだけで十分でした。UIViewシェニガンは必要ありません。
シム

1
@Lucienこれはまさにこの答えで言われたことです。正解はこちら:stackoverflow.com/a/43110590/566360
Andy

144

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

アップルのドキュメントは言います

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

ここ以外の単語に注意しください。.fillが使用される場合、水平UIStackViewは、配置されたサブビューのサイズを使用してそれ自体を垂直にサイズ変更しません。


3
これは、ハックなしの適切なソリューションです。ドキュメントを読むことは常に報われます!
イスラムQ.17年

3
これは受け入れられる解決策です。UIViewの回避策では、UILabelのテキストが別のサブビューの上に浮かびました。

14
実際には機能しません...私のスタックビューには3つのラベルがあります。線をゼロに、配置を中央に設定しました...ラベルが切り取られたままです。
MatterGoal

11
UILabelではなく UIStackView .alignmentに設定する必要があるのは、UIStackViewのものです。私はこれはそうあるべきだと思います.fill label.alignment = .centerstackView.alignment = .center
ae14

2
しかし、垂直方向のStackViewで複数行のUILableViewを機能させるにはどうすればよいですか?
ダチュン

42
  • まず、ラベルの行数を0に設定します
  • multiLine固定幅を指定しない限り、スタックビューはまだ大きくなりません。幅を修正すると、次のようにその幅に達すると、複数行に分割されます。

画面記録

スタックビューに固定幅を指定しないと、あいまいになります。スタックビューは、ラベルとともにどのくらい長くなりますか(ラベル値が動的な場合)?

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


3
スタックビューの幅が固定されておらず、デバイス(スーパービュー)の幅に比例している場合はどうなりますか。
OutOnAWeekend

はい、プロポーショナル幅も使用できます。重要なのは、ラベルが何らかの幅の後で壊れる必要があるかどうかですが、定義する必要があります。
Irfan、2016年

指定することができ@AnandKumar preferredMaxLayoutWidthviewDidLayoutSubviewsのあなたのラベルのためUIViewControllerかにlayoutSubviewsあなたがサブクラス場合UIView
Shyngys Kassymov 2016

4
これは受け入れられた答えであるはずです。スタックビューの全体のポイントは、スタックビューとその要素の間に制約を追加する必要がないことです
Honey

4
固定値を指定すると、自動レイアウトの目的が損なわれます
Islam Q.

17

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

self.myLabel.preferredMaxLayoutWidth = self.bounds.size.width;

3
これが私の本の正解です。UILabelをいじって複数の行を処理する必要がある場合は、本当にそれをpreferredMaxLayoutWidthにする必要があります。それなしでも機能するかもしれませんが、それなしでは物事は非常に速くファンキーになり得ます。
2018

2
すべてがすべての答えを試しましたが、あなたの答え以外はすべて間違っていました。ありがとう!
レヴァン

これは私の問題を完全に解決し、ハックがはるかに少ないと感じます、ありがとうございます。
Ethan Zhao

ご回答有難うございます!私の場合、stackViewの配置は既にに設定されて.centerおり、UIView内にラベルを本当に必要としませんでした。
Fariza Zhumat

12

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

ここに画像の説明を入力してください


12
縦型のstackViewの場合、これを機能させるには、Distributionを「Fill」に設定する必要があります。
SnoopyProtocol

2
分布を「塗りつぶし」に設定することが修正の鍵です。
ディランムーア

縦型のUIStackViewの場合、子UILabelに上と下の制約を設定してすべてのテキストを展開して表示する必要があることがわかりました。
bruce1337

8

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

Swift 4の例:

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

5

私にとっての手品widthAnchorは、UIStackViewでし。

設定leadingAnchortrailingAnchor動作しませんが、設定centerXAnchorwidthAnchor正しくUILabel表示をしました。


4

iOS 9以降

コール [textLabel sizeToFit]UILabelのテキストを設定した後にます。

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


4

UIStackViewマルチラインで構成される垂直の完全な例は次のとおりですUILabel自動高さの。

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

ここに画像の説明を入力してください

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

3

UIStackViewプロパティを追加し、

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

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


3

以下は、内に改行を含む複数行ラベルのPlayground実装ですUIStackViewUILabel内部に何かを埋め込む必要はなく、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

1

システムレイアウトは、サブビューを描画するために、原点、幅、高さを把握する必要があります。この場合、すべてのサブビューは同じ優先度を持ち、そのため競合が発生します。レイアウトシステムはビュー間の依存関係を認識していません。

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


0

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


0

Xcode 9.2:

行数を0に設定するだけです。これを設定すると、ストーリーボードは奇妙に見えます。プロジェクトを実行する心配はありません。実行中は、ストーリーボードの設定に従ってすべてのサイズが変更されます。ストーリーボードのバグだと思います。 ここに画像の説明を入力してください

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

ここに画像の説明を入力してください


0

何がうまくいったか!

スタックビュー:位置合わせ:塗りつぶし、分布:塗りつぶし、スーパービューexに対する制約の比例幅。0.8、

ラベル:中央、線= 0




0

私にとっての問題は、スタックビューの高さが単純に短すぎるということでした。ラベルとスタックビューは、ラベルが複数行になるように適切に設定されていましたが、スタックビューが高さを十分に低くするために使用したコンテンツ圧縮の最初の犠牲者でした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.