UILabel은 레이블 크기에 맞게 텍스트를 자동 축소하지 않습니다.


119

난 내가 계산에이 상황에 따라 ..이 이상한 문제, 지금은 8 시간 이상 그것으로 메신저 거래를 UILabels동적으로 크기
예를 들어
나의 UIViewController이벤트와 나는 변화의 수신 UILabels크기를. 큰 것에서 작은 것까지. 내 크기 UILabel가 작아지고 필요한 올바른 크기를 얻지 만 내 텍스트 UILabel는 동일하고 동일한 글꼴 크기 등으로 유지됩니다. 전체 텍스트가 UILabel. 그래서 문제는 내 레이블에 맞게 텍스트를 만드는 방법 autoshrinking입니다.

xib에서 UILabels autoshrink선택되고 수도 0으로 설정되고 내 문자열에도 새 줄 기호 (\ n)가 있으며 linebreakmodewordwrap. 누군가 나와 지금과 같은 상황에 있었고 나를 도울 수 있습니까? 정말 감사하겠습니다.

미리 감사드립니다!

편집 : UILabel 최소 글꼴 크기가 10으로 설정 됨


설정 한 lable에 대한 글꼴의 최소 크기는 얼마입니까? 추가하십시오.
AJPatel

답변:


159

여전히 더 나은 솔루션을 찾고 있다면 이것이 당신이 원하는 것이라고 생각합니다.

제목 문자열을 레이블의 경계 사각형에 맞추기 위해 글꼴 크기를 줄여야하는지 여부를 나타내는 부울 값입니다 (이 속성은 numberOfLines속성이 1로 설정된 경우에만 유효 함 ).

이 속성을 minimumScaleFactor설정할 때도 설정해야합니다 (좋은 기본값은 0.5).

빠른

var adjustsFontSizeToFitWidth: Bool { get set }

목표 -C

@property(nonatomic) BOOL adjustsFontSizeToFitWidth;

레이블의 경계 사각형 내의 문자열에 맞게 문자 사이의 간격을 조정해야하는지 여부를 나타내는 부울 값입니다.

빠른

var allowsDefaultTighteningForTruncation: Bool { get set }

목표 -C

@property(nonatomic) BOOL allowsDefaultTighteningForTruncation;

소스 .


18
참고로는 minimumFontSizeiOS 6.0에서 더 이상 사용되지 않습니다. minimumScaleFactor대신 사용하십시오 .
lester

14
예, 자동 축소는 UILabel의 여러 줄에 대해 작동하지 않습니다. 이것을 상상해보십시오. 여러 줄로 된 텍스트가 있고 너비에 "맞도록"줄이려고합니다. 따라서 전체 텍스트를 한 줄에 맞게 축소해야합니까, 아니면 단어가 같은 줄에 유지되고 각 너비에 맞게 축소해야합니까? 후자가 가장 일반적인 경우이지만 단어가 여러 줄로 정렬되도록 설정되어 있음을 잊지 마십시오. 텍스트 자동 정렬이 비활성화 된 경우에도 모든 단어가 너비에 맞지 않으므로 글꼴 크기가 다른 텍스트의 각 줄을 마주해야합니다.
lester

2
여기 에 카테고리 가있는이 답변 은 꽤 좋다고 생각합니다 . 어쨌든 구현 한 것일 수도 있습니다. 이것은 분명히 Apple API에서 누락 된 부분이거나 축소가 여러 줄의 정적 텍스트에 대한 일반적인 사용 사례 여야한다고 생각하지 않을 수도 있습니다 .
lester

1
글쎄요, 그게 좋은 지적입니다.하지만 어쨌든, 제가 생각하기에 줄 수를 0으로 설정하면 하나 이상의 줄이있을 수 있다는 분명한 진술입니다. 그리고 autoshrink는 내가 추측하는 줄 번호에 의해 결정될 수 있습니다. 그러나 어쨌든, 일을 정리해 주셔서 감사합니다. 나는 내가 뭔가 잘못하고 있다고 생각했다. 카테고리는 좋은 생각입니다. 다른 프로젝트에서이 작업이 필요할 것 같습니다. 행운을 당신의 도움을 주셔서 감사합니다;)
루카스

4
@lester 현재 크기가 주어지면 레이블에 대해 선언 된 줄 수에 전체 텍스트가 표시되도록 축소되어야합니다. 각 선을 다른 크기로 만들려고 할 필요가 없습니다. 나는 이것을 알아낼 수 없다는 것이 정말 놀랍습니다. 따라서 표시 할 (잠재적으로) 긴 문자열이 있는 경우 여러 줄을 가질 수도 있고 자동 크기를 조정할 수도 있습니다 . 사랑 스럽네.
devios1 2013 년

125

이것이 AutoshrinkiOS 9.2, Xcode 7.2에서 UILabel 작업 (특히 6s Plus Storyboard의 4s 장치에 맞는 레이블 글꼴 높이)을 얻는 방법입니다 .

여기에 이미지 설명 입력

  • 줄 수는 0입니다.
  • 줄 바꿈 : 클립
  • 자동 축소 : 최소 글꼴 배율 0.25

15
라벨이 실제로 축소되는 데 필요한 세 가지 요소는 클립 줄 바꿈 설정이 누락되었습니다. 또한 다른 레이블 (자동 축소 될 수도 있음)에 인접하면 압축 / 허깅 우선 순위를 설정하거나 명시적인 너비 또는 높이 제한을 지정해야합니다. 이것은 현재 받아 들여진 대답이어야합니다.
Korey Hinton 2015

3
라인 수는 나를 위해 해냈습니다! 감사합니다
Michael

레이블에 특히 선행 및 후행에 대한 모든 제약 조건이 있는지 확인하십시오.
Mashhadi

2
Xcode8에서 동일한 옵션을 시도했지만 작동하지 않는 것으로 나타났습니다. 누구든지 이것에 대한 아이디어가 있으면 저를 도와주세요.
Ganesh

75

minimumFontSize iOS 6에서는 더 이상 사용되지 않습니다.

따라서 minimumScaleFactor대신 minmimumFontSize.

lbl.adjustsFontSizeToFitWidth = YES
lbl.minimumScaleFactor = 0.5

스위프트 5

lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5

잘 대답했습니다. 내 문제를 해결했습니다. 감사합니다
Abdul Yasin 2014 년

1
@AntonMatosov, 아니, 그렇지 않습니다!
Iulian Onofrei

2
예, 그렇습니다 (현재)-줄 바꿈을 Word Wrap 대신 Truncate Tail로 설정하면 ...
TheEye

21

또한 내 솔루션은 부울 label.adjustsFontSizeToFitWidth = YES입니다. 그러나. 인터페이스 빌더에서 Word Wrapping을 " CLIP "로 전환해야합니다 . 그런 다음 레이블을 자동 축소합니다. 이건 매우 중요합니다.


3
"Word Wrap"에서 "Clip"으로 변경했을 때만 Autoshrink가 작동했습니다.
NicJ 2015

줄 바꿈을 클립으로 변경했을 때 실제로 줄이 0 인 레이블에서 크기를 조정할 수있었습니다. 이것이 문서화되어 있으면 좋을 것입니다.
DesignatedNerd

12

Swift 3 (프로그래밍 방식)에서는 다음을 수행해야했습니다.

let lbl = UILabel()
lbl.numberOfLines = 0
lbl.lineBreakMode = .byClipping
lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5
lbl.font = UIFont.systemFont(ofSize: 15)

5

다음과 같이 쓸 수 있습니다.

UILabel *reviews = [[UILabel alloc]initWithFrame:CGRectMake(14, 13,270,30)];//Set frame
reviews.numberOfLines=0;
reviews.textAlignment = UITextAlignmentLeft;
reviews.font = [UIFont fontWithName:@"Arial Rounded MT Bold" size:12];
reviews.textColor=[UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:0.0/255.0 alpha:0.8]; 
reviews.backgroundColor=[UIColor clearColor];

이렇게 줄 수를 계산할 수 있습니다

CGSize maxlblSize = CGSizeMake(270,9999);
CGSize totalSize = [reviews.text sizeWithFont:reviews.font 
              constrainedToSize:maxlblSize lineBreakMode:reviews.lineBreakMode];

CGRect newFrame =reviews.frame;
newFrame.size.height = totalSize.height;
reviews.frame = newFrame;

CGFloat reviewlblheight = totalSize.height;

int lines=reviewlblheight/12;//12 is the font size of label

UILabel *lbl=[[UILabel alloc]init];
lbl.frame=CGRectMake(140,220 , 100, 25);//set frame as your requirement
lbl.font=[UIFont fontWithName:@"Arial" size:20];
[lbl setAutoresizingMask:UIViewContentModeScaleAspectFill];
[lbl setLineBreakMode:UILineBreakModeClip];
lbl.adjustsFontSizeToFitWidth=YES;//This is main for shrinking font
lbl.text=@"HelloHelloHello";

이것이 당신을 도울 것입니다 :-) 당신의 대답을 기다리고


그래서 내 레이블에 줄 수를 설정하면 텍스트가 자동 축소됩니까?
루카스

콘텐츠가 너비를 벗어난 경우 다음 줄로 이동합니다
Birju

헤이 당신이 제안한대로했는데 작동하지 않습니다. 왜 줄 수가 도움이 될까요?
루카스

당신은 바로 내가 그 유용하지를 시도하고 있지만 당신이 그렇게 할 동안 나는 해결책을 발견 내 옆에 대답
Birju

lbl.adjustsFontSizeToFitWidth = 예; 나를 위해 일했습니다!
개발자

4

결국 나는 내 대답을 찾지 못했습니다. 그리고 자동 축소가 여러 줄에서 작동하지 않는다고 생각합니다. 이 링크에서 제안을 사용 했습니다. 여러 줄이있는 UILabel의 자동 축소

해결책은 주어진 너비에서 텍스트 높이를 계산하고 텍스트가 더 큰 경우 글꼴 크기를 축소 한 다음 높이가 필요한 크기보다 작거나 같을 때까지 다시 동일하게 수행하는 것입니다.

이것이 구현하기가 왜 그렇게 어려운지 이해할 수 없습니다. 내가 뭔가를 놓치고 있다면 모두가 나를 고칠 수 있습니다 :)


여기에있는 다른 답변에 따라 누락 된 핵심은 Word Wrapping을 "Clip"으로 설정해야한다는 것입니다. 직관적이지 않지만 UILabel이 원하는 방식으로 자동 축소되도록하려면 이것이 필요합니다. 이것은 여러 줄 UILabel에서 작동합니다.
Duncan Babbage

4

이것은 Xcode 8.2.1 (8C1002)을 실행하는 Swift 3 용입니다.

내가 찾은 가장 좋은 해결책은 스토리 보드 또는 레이블의 IB에서 고정 너비를 설정하는 것입니다. 여백에 대한 제한으로 제약 조건을 설정하십시오. viewDidLoad에서 다음 코드 줄을 추가합니다.

override func viewDidLoad() {
            super.viewDidLoad()

            label.numberOfLines = 1
            label.adjustsFontSizeToFitWidth = true
            label.minimumScaleFactor = 0.5
        }

여백에 대한 레이블 제약

여백에 대한 고정 너비 레이블 제약

속성 관리자

이것은 매력처럼 작동했으며 새 줄로 넘치지 않고 이상한 문제없이 레이블 너비에 맞게 텍스트를 축소하며 Swift 3에서 작동합니다.


4

지금 쯤이면 기본 제공 UIKit기능이나 관련 프레임 워크의 일부가 될 것 같아서 좋은 질문 입니다. 다음은 질문에 대한 좋은 시각적 예입니다.

글꼴 크기 조정 애니메이션

쉬운 방법은 없지만 확실히 가능합니다. 이를 수행하는 한 가지 방법은보기의 경계에 합리적으로 가까운 글꼴을 찾을 때까지 다른 글꼴 크기를 프로그래밍 방식으로 시도하는 것입니다. 또는 의 boundingRect()기능을 사용하여이를 수행 할 수 있습니다 . 예를 들면 :NSStringNSAttributedString

let string = "This is a test"
let infiniteSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height:CGFloat.greatestFiniteMagnitude)
let size = string.boundingRect(with: infiniteSize, options: [], attributes: [.font: UIFont.systemFont(ofSize: avgSize)] context: nil).size

완전한 무차별 대입 방식보다 더 효율적으로 이진 검색을 수행 할 수 있습니다. 정말 강력한 것을 찾고 있다면 올바른 단어 줄 바꿈 및 iOS 글꼴 캐싱 성능을 포함하여 약간 더 관련된 고려 사항도 있습니다.

화면에 텍스트를 쉽게 표시하는 데에만 관심이 있다면 Swift로 강력한 구현을 개발했으며,이 구현은 프로덕션 앱에서도 사용하고 있습니다. UIView여러 줄을 포함하여 모든 입력 텍스트에 대해 효율적인 자동 글꼴 크기 조정 기능이있는 하위 클래스입니다. 사용하려면 다음과 같이하면됩니다.

let view = AKTextView()
// Use a simple or fancy NSAttributedString
view.attributedText = .init(string: "Some text here")
// Add to the view hierarchy somewhere

그게 다야! 전체 소스는 https://github.com/FlickType/AccessibilityKit 에서 찾을 수 있습니다.

도움이 되었기를 바랍니다!


1
2018 년 11 월 : FlickType 및 AccessibilityKit이 비공개로 전환되었거나 제거 된 것으로 나타납니다.
Chris Paveglio 2018

3

iOS 9에서는 다음을 수행해야했습니다.

  1. 레이블의 왼쪽과 오른쪽에서 superview에 제약 조건을 추가합니다.
  2. 줄 바꿈 모드를 IB에서 클리핑으로 설정합니다.
  3. IB에서 줄 수를 1로 설정합니다.

누군가는 줄 수를 0으로 설정하도록 권장했지만 나에게는 레이블이 여러 줄로 이동했습니다.


이것은 나를 위해 트릭을했습니다. 방금 정적 셀에서 a UILabel및 a UITextField를 선택하고 "Resolve AutoLayout Issues"및 "Add Missing Constraints"를 클릭했습니다. 모든 것이 정렬되었지만 Autoshrink는 "Add Missing Constraints"가 제약 조건을 추가하지 않은 레이블까지의 거리를 알아야했습니다.
Adrian

2

init Label을 할당 한 후 다음 코드를 작성할 수 있다고 생각합니다.

UILabel* lbl = [[UILabel alloc]initWithFrame:CGRectMake(0, 10, 280, 50)];
lbl.text = @"vbdsbfdshfisdhfidshufidhsufhdsf dhdsfhdksbf hfsdh fksdfidsf sdfhsd fhdsf sdhfh sdifsdkf ksdhfkds fhdsf dsfkdsfkjdhsfkjdhskfjhsdk fdhsf ";
[lbl setMinimumFontSize:8.0];
[lbl setNumberOfLines:0];
[lbl setFont:[UIFont systemFontOfSize:10.0]];
lbl.lineBreakMode = UILineBreakModeWordWrap;
lbl.backgroundColor = [UIColor redColor];
[lbl sizeToFit];
[self.view addSubview:lbl];

그것은 나와 잘 일하고 있습니다 그것을 사용하십시오


1
감사합니다.하지만 이것은 내가 이해하는대로 필요한 최소 글꼴을 계산하거나 축소하지 않으며 최소 글꼴이 보통보다 큰 이유는 무엇입니까?
Lukas

2

2 년이 지났지 만이 문제는 아직 해결되지 않았습니다.

iOS 8 / XCode 6.1에서는 UILabel( UITableViewCellAutoLayout이 켜져 있고 유연한 제약 조건을 사용하여 에서 생성 된 ) 텍스트 문자열에 맞게 자체 크기가 조정되지 않는 경우가있었습니다.

솔루션은 이전과 마찬가지로 텍스트를 설정 한 다음을 호출 하는 것이 었습니다 sizeToFit.

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    . . .
    cell.lblCreatedAt.text = [note getCreatedDateAsString];
    [cell.lblCreatedAt sizeToFit];
}

(한숨.)


1

방법은 다음과 같습니다. 다음 messageLabel이 원하는 효과를 원하는 레이블이라고 가정합니다. 이제 다음 간단한 코드 줄을 시도해보십시오.

    //SET THE WIDTH CONSTRAINTS FOR LABEL.
    CGFloat constrainedWidth = 240.0f;//YOU CAN PUT YOUR DESIRED ONE,THE MAXIMUM WIDTH OF YOUR LABEL.
 //CALCULATE THE SPACE FOR THE TEXT SPECIFIED.
    CGSize sizeOfText=[yourText sizeWithFont:yourFont constrainedToSize:CGSizeMake(constrainedWidth, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
    UILabel *messageLabel=[[UILabel alloc] initWithFrame:CGRectMake(20,20,constrainedWidth,sizeOfText.height)];
    messageLabel.text=yourText;
    messageLabel.numberOfLines=0;//JUST TO SUPPORT MULTILINING.

대답 해 주셔서 감사합니다.하지만 라벨 높이를 계산할 필요가없고 크기가 고정되어 있으며 필요한 경우 글꼴 크기가 작아 져야합니다.
Lukas

1

numberOfLines > 1 내가 한 일이 이와 같은 조건을 만들면 작동하지 않습니다.

if(lblRecLocation.text.length > 100)
    lblRecLocation.font = [UIFont fontWithName:@"app_font_name" size:10];

0

파티에 늦게 왔지만 한 줄에 하나의 단어가 있어야한다는 추가 요구 사항이 있었기 때문에이 추가 사항이 나에게 트릭을 제공했습니다.

label.numberOfLines = [labelString componentsSeparatedByString:@" "].count;

Apple Docs 는 다음과 같이 말합니다.

일반적으로 레이블 텍스트는 font 속성에서 지정한 글꼴로 그려집니다. 그러나이 속성이 YES로 설정되고 텍스트 속성의 텍스트가 레이블의 경계 사각형을 초과하면 수신자는 문자열이 맞거나 최소 글꼴 크기에 도달 할 때까지 글꼴 크기를 줄이기 시작합니다. iOS 6 및 이전 버전에서이 속성은 numberOfLines 속성이 1로 설정된 경우에만 유효합니다.

그러나 이것은 거짓말입니다. 내가 말하는 거짓말! 모든 iOS 버전에 해당됩니다. 사용시 즉,이 사실 UILabel내에 UICollectionViewCell크기가 지정 레이아웃 (예를 통해 런타임에 동적으로 조정 제약에 의해 결정되는.self.menuCollectionViewLayout.itemSize = size ).

와 함께 사용하면 그래서 adjustsFontSizeToFitWidthminimumScaleFactor프로그램 설정, 이전 답변에서 언급 한 바와 같이, numberOfLines단어 수에 따라 자동 축소 문제를 해결했다. 단어 수 또는 문자 수를 기반으로 유사한 작업을 수행하면 "충분히 가까운"솔루션이 생성 될 수 있습니다.


0

Swift 4 (프로그래밍 방식) :

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200.0, height: 200.0))
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 0

label.text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."

view.addSubview(label)

0

스위프트 4, Xcode 9.4.1

나를 위해 일한 솔루션 : 컬렉션 뷰 셀 내에 레이블 이 있었고 레이블 텍스트가 잘리고있었습니다. 스토리 보드에서 아래와 같이 속성을 설정합니다.

Lines = 0
LineBreak = Word Wrap
Set yourlabel's leading and trailing constraint = 0 (using Autolayout)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.