2017-11-09 10 views
1

2つのラベル(たとえばleftLabel、rightLabel)が必要で、leftLabelが伸び、rightLabelが1文字のアイコン(「>」など)に収まるように水平に置きます。したがって、両方のラベルのレイアウトが正当化されます。2つの揃えられたラベルを持つ水平方向のUIStackView

結果の下に与え
class StackViewController: UIViewController { 
    /// Main vertical outer/container stack view that pins its edges to this view in storyboard (i.e. full screen) 
    @IBOutlet weak private var containerStackView: UIStackView! 

    private var leftLabel: UILabel = { 
     let leftLabel = UILabel(frame: .zero) 
     leftLabel.font = .preferredFont(forTextStyle: .body) 
     leftLabel.numberOfLines = 0 // no text truncation, allows wrap 
     leftLabel.backgroundColor = .orange 
     return leftLabel 
    }() 
    private var rightLabel: UILabel = { 
     let rightLabel = UILabel(frame: .zero) 
     rightLabel.font = .preferredFont(forTextStyle: .body) 
     // Set CHCR as high so that label sizes itself to fit the text 
     rightLabel.setContentHuggingPriority(UILayoutPriorityDefaultHigh, for: .horizontal) 
     rightLabel.setContentCompressionResistancePriority(UILayoutPriorityDefaultHigh, for: .horizontal) 
     rightLabel.backgroundColor = .green 
     return rightLabel 
    }() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     prepareAndLoadSubViews() 
     // Note, the text required to be set in viewDidAppear, not viewDidLoad, otherwise rightLabel stretches to fill!! 
     leftLabel.text = "This is left label text that may go in multiple lines" 
     rightLabel.text = ">" // Always a single character 
    } 

    /// Dynamically creates a horizontal stack view, with 2 labels, in the container stack view 
    private func prepareAndLoadSubViews() { 
     /// Prepare the horizontal label stack view and add the 2 labels 
     let labelStackView = UIStackView(arrangedSubviews: [leftLabel, rightLabel]) 
     labelStackView.axis = .horizontal 
     labelStackView.distribution = .fillProportionally 
     labelStackView.alignment = .top 
     containerStackView.addArrangedSubview(labelStackView) 
     containerStackView.addArrangedSubview(UIView()) 
    } 
} 

(すなわちleftLabel幅がビューデバッガでは0です) - -

enter image description here

この...

enter image description here

のようにこれは私が持っているコードです。

注:viewDidAppearでテキストセットコードを移動すると正常に動作します。

override func viewDidAppear(_ animated: Bool) { 
    super.viewDidAppear(animated) 
    // Note, the text required to be set in viewDidAppear, not viewDidLoad, otherwise rightLabel stretches to fill!! 
    leftLabel.text = "This is left label text that may go in multiple lines" 
    rightLabel.text = ">" // Always a single character 
} 

なぜですか? そして、viewDidLoadの前にコンテンツの抱擁/圧縮抵抗の優先順位を設定できますか?

答えて

0

あなたのコードでかなり遊んでいましたが、私はそれを動作させることができませんでした。これは、UIStackViewを別のUIStackViewに追加したときに発生するバグだと思います。 UIStackViewコードが1つしかない場合、コードは正常に動作します。

私はあなたのケースの修正を提供することはできませんが、実際にはあなたの2つのラベルにはUIStackViewを使用する必要はありません。あなたが非表示にして表示する複数のアレンジされたサブビューがあり、自動的にアレンジする必要がある場合は、UIStackViewは素晴らしいです。ちょうど2つの "静的な"ラベルの場合、私はそれが少し過剰なものだと思います。

2つのラベルをUIViewに追加してレイアウトの制約をラベルに設定することで、後の作業を達成できます。本当に簡単です:

class StackViewController: UIViewController { 

    @IBOutlet weak var containerStackView: UIStackView! 

    private var leftLabel: UILabel = { 
     let leftLabel = UILabel(frame: .zero) 
     leftLabel.font = .preferredFont(forTextStyle: .body) 
     leftLabel.numberOfLines = 0 
     leftLabel.backgroundColor = .orange 
     leftLabel.translatesAutoresizingMaskIntoConstraints = false 
     leftLabel.numberOfLines = 0 
     return leftLabel 
    }() 
    private var rightLabel: UILabel = { 
     let rightLabel = UILabel(frame: .zero) 
     rightLabel.font = .preferredFont(forTextStyle: .body) 
     rightLabel.setContentHuggingPriority(UILayoutPriority.required, for: .horizontal) 
     rightLabel.backgroundColor = .green 
     rightLabel.translatesAutoresizingMaskIntoConstraints = false 
     return rightLabel 
    }() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     prepareAndLoadSubViews() 
     leftLabel.text = "This is left label text that may go in multiple lines" 
     rightLabel.text = ">" 
    } 

    private func prepareAndLoadSubViews() { 
     let labelContainerView = UIView() 
     labelContainerView.addSubview(leftLabel) 
     labelContainerView.addSubview(rightLabel) 

     NSLayoutConstraint.activate([ 
      leftLabel.leadingAnchor.constraint(equalTo: labelContainerView.leadingAnchor), 
      leftLabel.topAnchor.constraint(equalTo: labelContainerView.topAnchor), 
      leftLabel.bottomAnchor.constraint(equalTo: labelContainerView.bottomAnchor), 

      rightLabel.leadingAnchor.constraint(equalTo: leftLabel.trailingAnchor), 
      rightLabel.topAnchor.constraint(equalTo: labelContainerView.topAnchor), 
      rightLabel.bottomAnchor.constraint(equalTo: labelContainerView.bottomAnchor), 
      rightLabel.trailingAnchor.constraint(equalTo: labelContainerView.trailingAnchor) 
     ]) 

     containerStackView.addArrangedSubview(labelContainerView) 
     containerStackView.addArrangedSubview(UIView()) 
    } 
} 
+0

あなた自身とアドバイスをお試しいただきありがとうございます。あなたは正しいです、私は制約を使用して同じレイアウトを達成することができます。しかし、データに基づいてrightLabelを非表示にする追加の要件があります。つまり、leftLabelは全幅に伸びる必要があります。自動レイアウトでこれを実現するには、追加の制約をほとんど必要としません。また、このセル全体では、すぐにいくつかのラベル/イメージビューを追加しなければならないので、スタックビューを制約よりも使用することを好むでしょう。 – Ashok

関連する問題