답변:
정답은 여기에 있습니다 : https :
//.com/a/43110590/566360
UILabel
돌며 UIView
(편집기 -> 삽입에서 ->보기)UILabel
받는 사람을 UIView
(예를 들어, 수퍼 제약 공간, 위쪽 공간, 선행 공백을 후행)이 UIStackView
(가) 스트레칭합니다 UIView
제대로 맞게, 그리고는 UIView
를 제한합니다 UILabel
여러 줄에.
UIView
shenanigans가 필요 하지 않습니다.
보기 UILabel
중 하나 인 가로 스택보기의 경우 인터페이스 빌더에서 먼저 설정하십시오 label.numberOfLines = 0
. 이렇게하면 레이블에 둘 이상의 줄이 있어야합니다. 스택 뷰가있을 때 처음에는 작동하지 않았습니다 stackView.alignment = .fill
. 작동하려면 간단히 설정하십시오 stackView.alignment = .center
. 이제 레이블을에서 여러 줄로 확장 할 수 있습니다 UIStackView
.
애플 설명서를 말한다
채우기 정렬을 제외한 모든 정렬의 경우 스택보기는 스택의 축에 수직 인 크기를 계산할 때 각 정렬 된보기의 고유 ContentSize 속성을 사용합니다.
여기를 제외한 단어를 참고 하십시오. 시 .fill
수평을 사용 UIStackView
자체를 조정되지 않는 수직 파단 배치 크기를 사용.
.alignment
당신은 아무것도로 설정하되 가지고 있다는 UIStackView의 .fill
하지 주어진 예에서 혼란 조금있는 UILabel의, label.alignment = .center
. 나는 이것이되어야한다고 생각한다stackView.alignment = .center
multiLine
고정 너비 를 지정 하지 않으면 스택 뷰가 계속 커지지 않습니다 . 너비를 고정하면 그림과 같이 너비에 도달하면 여러 줄로 나뉩니다.스택 뷰에 고정 너비를 제공하지 않으면 상황이 모호해집니다. 라벨과 함께 스택 뷰가 얼마나 오래 커 집니까 (레이블 값이 동적 인 경우)?
이것이 문제를 해결할 수 있기를 바랍니다.
preferredMaxLayoutWidth
년 viewDidLayoutSubviews
에 레이블 UIViewController
또는에서 layoutSubviews
당신이 서브 클래스 경우 UIView
.
preferredMaxLayoutWidth를 UILabel로 설정하면 나를 위해 일했습니다.
self.myLabel.preferredMaxLayoutWidth = self.bounds.size.width;
.center
있으며 실제로 UIView 내에서 레이블이 필요하지 않았습니다.
위의 모든 제안을 시도한 후에 UIStackView에 대한 속성 변경이 필요하지 않다는 것을 알았습니다. UILabels의 속성을 다음과 같이 변경합니다 (레이블은 이미 세로 스택보기에 추가됩니다).
스위프트 4 예제 :
[titleLabel, subtitleLabel].forEach(){
$0.numberOfLines = 0
$0.lineBreakMode = .byWordWrapping
$0.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)
}
iOS 9 이상
[textLabel sizeToFit]
UILabel 텍스트를 설정 한 후 호출 하십시오.
sizeToFit는 preferredMaxWidth를 사용하여 여러 줄 레이블을 다시 레이아웃합니다. 레이블은 stackView의 크기를 조정하여 셀의 크기를 조정합니다. 스택 뷰를 컨텐츠 뷰에 고정하는 것 외에 추가 제약이 필요하지 않습니다.
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])
}
}
다음은 내부에 줄 바꿈이있는 여러 줄 레이블의 놀이터 구현입니다 UIStackView
. 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
시스템 레이아웃은 서브 뷰를 그릴 때 원점, 너비 및 높이를 파악해야합니다.이 경우 모든 서브 뷰의 우선 순위가 동일합니다. 즉, 충돌이 발생합니다. 레이아웃 시스템은 뷰간에 종속성을 알지 못합니다.
스택 하위 뷰 압축 설정은 스택 뷰가 가로 또는 세로 및 여러 줄이되기를 원하는 것에 따라 여러 줄의 문제를 해결합니다. stackOtherSubviews .setContentCompressionResistancePriority(.defaultHight, for: .horizontal)
lblTitle.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
나를 위해 일한 것!
스택 뷰 : 정렬 : 채우기, 분포 : 채우기, 수퍼 뷰에 대한 제한 폭 너비 ex. 0.8,
레이블 : 중심 및 선 = 0
여전히 작동하지 않는 사람을 위해. 해당 UILabel에서 최소 글꼴 크기로 자동 축소를 설정하십시오.
그것은 @ Andy 's Answer와 거의 같지만 UILabel
추가 UIStackview
로 수직으로 추가 할 수 있습니다 .