iOS : 자동 레이아웃의 여러 줄 UILabel


183

자동 레이아웃으로 매우 기본적인 레이아웃 동작을 달성하는 데 문제가 있습니다. 내 뷰 컨트롤러는 IB에서 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

맨 위 레이블은 제목 레이블이며, 몇 줄인지 알 수 없습니다. 모든 텍스트 줄을 표시하려면 제목 레이블이 필요합니다. 제목 바로 아래에 다른 두 개의 레이블과 작은 이미지를 배치해야하지만 키가 커야합니다. 레이블과 작은 이미지 사이의 세로 간격 제약 조건과 제목 레이블과 해당 슈퍼 뷰 사이의 상단 간격 제약 조건과 작은 이미지와 슈퍼 뷰 사이의 하단 간격 제약 조건을 설정했습니다. 흰색 UIView에는 높이 제한이 없으므로 하위 뷰를 포함하도록 세로로 늘려야합니다. 제목 레이블의 줄 수를 0으로 설정했습니다.

문자열에 필요한 줄 수에 맞게 제목 레이블의 크기를 조정하려면 어떻게해야합니까? 자동 레이아웃을 사용하고 있기 때문에 setFrame 메서드를 사용할 수 없다는 것을 이해하고 있습니다. 그리고 다른 레이아웃이 제목 레이블 아래에 있어야하기 때문에 자동 레이아웃을 사용해야합니다 (따라서 제약 조건).

어떻게하면 되나요?


3
나는 비슷한 문제로 싸우고 있습니다. 그러나 나는 여전히 최상위 레이블을 내용에 맞게 높이를 동적으로 조정하기 위해 고심하고 있습니다. 이것을 어떻게 달성 했습니까?
— jbandi

1
@mwhuss의 답변을 허용 된 답변으로 표시하십시오.
— jemmons

1
필요한 결과를 얻었습니까?
— Aniruddha

이를 확인, 당신은 코드의 한 줄 추가해야 그나마 stackoverflow.com/a/36862795/4910767을
— Badal 샤

답변:


254

사용 -setPreferredMaxLayoutWidth상의 UILabel나머지를 처리해야하고 자동 레이아웃.

[label setPreferredMaxLayoutWidth:200.0];

preferredMaxLayoutWidth 의 UILabel 문서를 참조하십시오 .

최신 정보:

height스토리 보드 의 제약 조건 만으로 설정하면 Greater than or equal to되며 PreferredMaxLayoutWidth 를 설정할 필요가 없습니다.


8
어쨌든 인터페이스 빌더 에서이 작업을 수행합니까?
— Sjoerd Perfors

12
또한 IB의 높이 제한을보다 크거나 같게 설정하십시오. "
— jowie

10
알림 : numberOfLines 속성을 설정해야합니다.
— 리튬 Fumin

2
네, 원하는 최대 너비를 사용하십시오.
— mwhuss

4
간단하지만 유익한 쓰기에 대해서는 devetc.org/code/2014/07/07/auto-layout-and-views-that-wrap.html 을 확인 하고 확인 하는 방법 은 stackoverflow.com/a/29180323/1529675 를 참조하십시오. 애니메이션 GIF (내 글이 아니라 Google을 통해 찾았습니다)preferredMaxLayoutWidth
— tboyce12

213

라벨 세트 라인 수를 0으로 확장하고 자동 레이아웃 높이를> = x로 설정하는 것이 더 중요합니다. 자동 레이아웃이 나머지 작업을 수행합니다. 이전 요소를 기반으로 다른 요소를 포함하여 올바르게 배치 할 수도 있습니다.

자동 레이아웃


이 방법으로 문제가 해결되지 않으면 후속보기에서 자동 레이아웃이 여러 줄보기의 크기를 조정할 수 없도록하는 Cory Imdieke의 답변을 참조하십시오.
— Tom Howard

1
이것은 테이블 뷰 셀 내에서 나를 위해 일한 유일한 대답입니다. 또한 고정 된 수의 행 (0 / 무제한 대신)으로 작동합니다.
— bgolson

명시 적으로 선호하는 최대 너비를 설정하면 작동하지 않으므로이 기술을 사용할 때 IB에서 자동으로 설정되어 있는지 확인하십시오. 건배
— jmc

자동 최대 너비 설정은 iOS8에서만 사용할 수 있습니다. 또한 내 이해에서 높이를 자동으로 조정하므로 내 경험에 따라 높이 제한을 설정할 필요가 없습니다. 이것은 명시 적 너비를 사용하여 나를 위해 일했습니다.
— Tony

1
이것은 나를 위해 작동하지 않았습니다. stackoverflow.com/a/13032251/1529675 가 정답 이라고 생각 합니다.
— tboyce12

48

출처 : http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html

여러 줄 문자의 고유 내용 크기

UILabel 및 NSTextField의 내장 컨텐츠 크기는 여러 줄로 된 텍스트에는 모호합니다. 텍스트의 높이는 선의 너비에 따라 달라지며 구속 조건을 해결할 때 결정되지 않습니다. 이 문제를 해결하기 위해 두 클래스 모두 preferredMaxLayoutWidth라는 새로운 속성을 가지며, 이는 고유 컨텐츠 크기를 계산하기위한 최대 선 너비를 지정합니다.

우리는 일반적으로이 값을 미리 알지 못하므로이를 올바르게 달성하기 위해서는 2 단계 접근 방식이 필요합니다. 먼저 자동 레이아웃이 작동하게 한 다음 레이아웃 패스의 결과 프레임을 사용하여 원하는 최대 너비를 업데이트하고 레이아웃을 다시 트리거합니다.

- (void)layoutSubviews
{
    [super layoutSubviews];
    myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
    [super layoutSubviews];
}

레이블이 프레임 세트를 가져 오려면 [super layoutSubviews]에 대한 첫 번째 호출이 필요하지만 변경 후 레이아웃을 업데이트하려면 두 번째 호출이 필요합니다. 두 번째 호출을 생략하면 NSInternalInconsistencyException 오류가 발생합니다. 제약 조건을 업데이트해야하는 레이아웃 패스를 변경했지만 레이아웃을 다시 트리거하지 않았기 때문입니다.

레이블 서브 클래스 자체에서도이를 수행 할 수 있습니다.

@implementation MyLabel
- (void)layoutSubviews
{
    self.preferredMaxLayoutWidth = self.frame.size.width;
    [super layoutSubviews];
}
@end

이 경우 layoutSubviews가 호출 될 때 레이블 자체에 이미 프레임이 있으므로 [super layoutSubviews]를 먼저 호출 할 필요가 없습니다.

뷰 컨트롤러 수준에서이 조정을 수행하기 위해 viewDidLayoutSubviews에 연결합니다. 이 시점에서 첫 번째 자동 레이아웃 패스의 프레임이 이미 설정되어 있으며이를 사용하여 원하는 최대 너비를 설정할 수 있습니다.

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
    [self.view layoutIfNeeded];
}

마지막으로, 레이블의 내용 압축 저항 우선 순위보다 우선 순위가 높은 레이블에 명시 적 높이 제한이 없는지 확인하십시오. 그렇지 않으면 계산 된 내용의 높이보다 우선합니다. 라벨 높이에 영향을 줄 수있는 모든 구속 조건을 확인하십시오.


감사합니다. 코드뿐만 아니라 하위 클래스뿐만 아니라 뷰 컨트롤러에서도이를 수행하는 방법에 대한 설명과 예제에 대해 감사드립니다.
— djibouti33

뷰 컨트롤러에서 이것을 시도하고 있는데 viewWillAppear 및 viewDidAppear 후에 viewDidLayoutSubviews가 호출됩니다. viewDidAppear 후 레이블 크기가 올바르게 조정되면 플래시가 발생합니다. 이것을 피할 수있는 방법이 있습니까? 사용자가 아무것도보기 전에 크기 조정을 완료하는 방법이 있습니까? 필자의 경우 여러 줄 레이블이 tableHeaderView에 있으므로이 예제를 사용하여 레이블을 기반으로 헤더보기의 높이를 조정하고 있습니다 ( stackoverflow.com/questions/20982558/… )
— djibouti33

@ djibouti33 문제를 쉽게 확인할 수 있도록 최소 샘플 코드 (예 : github repo 형식)를 제공 할 수 있습니까?
— Anton Matosov

@Anton에게 감사합니다. 우리의 디자인은 UITableView에서 UICollectionView로 전환되었으며, 다행히도이 동작을 보지 못했습니다. 작은 샘플 프로젝트를 만들기 위해 git history에 도달하면 알려 드리겠습니다.
— djibouti33

iOS 9 sim에서 실행하기 시작한 이후 문제가되었지만 iOS 8에서 테스트하면 문제가 시작되었습니다. 최대 너비를 수동으로 설정해야합니다.
— naz

17

나는이 정확한 시나리오와 싸우고 있었지만 필요에 따라 크기를 조정하고 축소하는 데 필요한 몇 가지 추가 견해를 가지고있었습니다. 그것은 나를 미치게 만들었지 만 마침내 알아 냈습니다.

핵심은 다음과 같습니다. Interface Builder는 뷰를 추가하고 이동할 때 추가 제약 조건을 적용하기를 좋아하지만 눈치 채지 못할 수도 있습니다. 내 경우에는 절반과 아래로 내려 가서 기본보기와 그 사이의 크기를 지정하는 추가 제약이 있습니다. 즉, 제약 조건에 위배되므로 그보다 더 큰 크기를 조정할 수 없습니다.

이런 경우인지 알 수있는 쉬운 방법은 레이블 크기를 수동으로 조정하는 것입니다. IB는 당신이 그것을 키울 수 있습니까? 그렇다면 아래 레이블이 예상대로 이동합니까? 구속 조건이 뷰를 어떻게 이동시키는 지 확인하기 위해 크기를 조정하기 전에이 두 가지를 모두 확인하십시오.

IB 메뉴

뷰가 멈춘 경우, 그 아래에있는 뷰를 따르고 그 중 하나에 제한을두기위한 상단 공간이 없는지 확인하십시오. 그런 다음 레이블의 줄 수 옵션이 0으로 설정되어 있는지 확인하고 나머지는 처리해야합니다.


그렇습니다. 많은 일을 한 후에 나는 원하는 효과를 얻을 수있었습니다. 원하는 제약 조건에 대해 매우 신중하게 생각해야합니다. IB가 예상치 못한 제약 조건을 끊임없이 던지는 데 도움이되지 않습니다.
— James Harpe

5

다음이 필요하다는 것을 알았습니다.

  • 최고 제약
  • 선행 구속 조건 (예 : 왼쪽)
  • 후행 구속 조건 (예 : 오른쪽)
  • 콘텐츠 포옹 우선 순위를 가로로 낮게 설정하면 텍스트가 짧은 경우 지정된 공간을 채 웁니다.
  • 내용 압축 저항을 가로로 낮게 설정하면 더 넓어지지 않고 줄 바꿈됩니다.
  • 줄 수를 0으로 설정하십시오.
  • 줄 바꿈 모드를 자동 줄 바꿈으로 설정하십시오.

이것은 xcode9에서 작동합니다. 나는 레이블 높이 제한으로 아무것도 할 필요가 없었습니다 (아무것도 없습니다) : 레이블이 제한되면 (트레일 링, 선행, 상단 및 하단) 최근 상자에서 작동합니다. uikit는 나머지를 수행
— Anton Tropashko

콘텐츠 포옹 우선 순위는 내 문제였습니다. 압축 저항뿐만 아니라 그 속성을 알게 해 주셔서 감사합니다. 한 시간 동안 문제를 해결하도록 도와주었습니다.
— David Gay

0

주제에 대한 많은 주제에서 발견 된 다른 솔루션 중 어느 것도 내 경우에 완벽하게 작동하지 않았습니다 (동적 테이블 뷰 셀의 x 동적 멀티 라인 레이블).

나는 그것을 할 수있는 방법을 찾았다.

레이블에 제약 조건을 설정하고 여러 줄 속성을 0으로 설정 한 후 UILabel의 하위 클래스를 만듭니다. 내 AutoLayoutLabel이라고 전화했습니다.

@implementation AutoLayoutLabel

- (void)layoutSubviews{
    [self setNeedsUpdateConstraints];
    [super layoutSubviews];
    self.preferredMaxLayoutWidth = CGRectGetWidth(self.bounds);
}

@end

0

텍스트 줄 바꿈 레이블이있는 UITableViewCell이 있습니다. 다음과 같이 텍스트 줄 바꿈을 수행했습니다.

1) UILabel 제약 조건을 다음과 같이 설정하십시오.

여기에 이미지 설명을 입력하십시오

2) 설정 번호 줄의 0.

3) UITableViewCell에 UILabel 높이 제한이 추가되었습니다.

@IBOutlet weak var priorityLabelWidth: NSLayoutConstraint!

4) UITableViewCell에서 :

priorityLabel.sizeToFit()
priorityLabelWidth.constant = priorityLabel.intrinsicContentSize().width+5

-12

한 가지 방법은 ... 텍스트 길이가 길어질수록 레이블 텍스트의 글꼴 크기를 변경 (감소)하려고합니다.

Label.adjustsFontSizeToFitWidth = YES;

1
뷰 컨트롤러의 다른 인스턴스가 일관된 모양을 갖기를 원하므로 글꼴 크기를 변경하고 싶지 않습니다.
— James Harpe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.