2017-11-09 33 views
1

2 개의 레이블 (예 : leftLabel, rightLabel)을두고 가로 레이블을 배치하여 leftLabel이 늘어나고 rightLabel이 단일 문자 아이콘 (예 : ">")에 맞도록하십시오. 따라서 두 레이블 레이아웃은 양쪽 정렬됩니다. 이처럼 ...2 개의 양쪽 맞춤 레이블이있는 가로 방향의 UIStackView

enter image description here

입니다 코드 내가 가진 - 결과 아래에 제공

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

참고 : 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 코드 하나만 있으면 잘 작동합니다.

귀하의 사례에 대한 해결책을 제공 할 수는 없지만 IMHO에서는 실제로 귀하의 2 개 라벨에 UIStackView을 사용할 필요가 없습니다. UIStackView은 숨기고 표시하고 자동으로 정렬해야하는 정렬 된 하위보기가 여러 개있는 경우 유용합니다. 단지 두 개의 "정적 인"레이블의 경우 약간 과잉이라고 생각합니다.

두 개의 레이블을 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

자신과 조언을 시도해 주셔서 감사합니다. 맞습니다, 제약 조건을 사용하여 동일한 레이아웃을 얻을 수 있습니다. 그러나 leftLabel을 전폭 늘려야 데이터를 기반으로 rightLabel을 숨길 수있는 추가 요구 사항이 있습니다. 자동 레이아웃을 통해이를 달성하려면 몇 가지 추가적인 제약이 필요합니다. 또한,이 셀 전체적으로 나는 몇개의 라벨/이미지 뷰를 곧 추가해야하므로, 제약 조건보다 스택 뷰를 사용하는 것을 선호합니다. – Ashok