developer tip

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

optionbox 2020. 8. 2. 18:23
반응형

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


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

내에서 xib, UILabels autoshrink또한, 체크 라인의 수를 0으로 설정하고, 또한 내 문자열은 줄 바꿈 문자 (\ n)을 가지고 있으며, 내가 선택한 linebreakmode을wordwrap. 어쩌면 내가 지금과 같은 상황에 처해 있고 나를 도울 수 있습니까? 정말 고맙겠습니다.

미리 감사합니다!

편집 : UILabel 최소 글꼴 크기가 10으로 설정되었습니다


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

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

@property(nonatomic) BOOL adjustsFontSizeToFitWidth

문자의 간격을 레이블의 경계 사각형 안에있는 문자열에 맞게 조정해야하는지 여부를 나타내는 부울 값입니다. (더 이상 사용되지 않음)

@property(nonatomic) BOOL adjustsLetterSpacingToFitWidth

소스 .


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

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

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

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

minimumScaleFactor대신을 사용하십시오 minmimumFontSize.

lbl.adjustsFontSizeToFitWidth=YES;
lbl.minimumScaleFactor=0.5;

또한 내 솔루션은 부울 레이블입니다 .adjustsFontSizeToFitWidth = YES; 그러나. 인터페이스 작성기에서 단어 줄 바꿈 스위치를 " CLIP "로 전환해야합니다 . 그런 다음 레이블을 자동 축소하십시오. 이건 매우 중요합니다.


Swift 3에서 (프로그래밍 방식으로)이 작업을 수행해야했습니다.

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

당신은 다음과 같이 쓸 수 있습니다

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";

희망이 당신을 도울 것입니다 :-) 회신을 기다리고


이것은 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에서 작동합니다.


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

The solutions is to calulate text height at given width and if text is bigger, to shrink font size and then do he same again until the height is equal or less than your needed size.

I don't understand why this should be so hard to implement. If i'm missing something, everyone is welcome to correct me :)


I think you can write bellow code after alloc 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];

It is working with me fine Use it


Two years on, and this issue is still around...

In iOS 8 / XCode 6.1, I was sometimes finding that my UILabel (created in a UITableViewCell, with AutoLayout turned on, and flexible constraints so it had plenty of space) wouldn't resize itself to fit the text string.

The solution, as in previous years, was to set the text, and then call sizeToFit.

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

(Sigh.)


In iOS 9 I just had to:

  1. Add constraints from the left and right of the label to the superview.
  2. Set the line break mode to clipping in IB.
  3. Set the number of lines to 1 in IB.

Someone recommended setting number of lines to 0, but for me this just made the label go to multiple lines...


It's a great question, because it feels like that would be part of the built-in UIKit functionality or a related framework by now. Here's a good visual example of the question:

글꼴 크기 조정 애니메이션

There's no easy way around it, but it's definitely possible. One way to do this is to programmatically try different font sizes until you find one that fits reasonably close to the bounds of the view. You can accomplish this with the boundingRect() function of NSString or NSAttributedString. For example:

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

You can do a binary search to be more efficient than a complete brute force approach. There are also some considerations that are a bit more involved, including correct word wrapping and iOS font caching performance, if you're looking for something really robust.

If you only care about showing the text on the screen in an easy way, I have developed a robust implementation in Swift, which I'm also using in a production app. It's a UIView subclass with efficient, automatic font scaling for any input text, including multiple lines. To use it, you'd simply do something like:

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

That's it! You can find the complete source here: https://github.com/FlickType/AccessibilityKit

Hope this helps!


Here's how to do it.Suppose the following messageLabel is the label you want to have the desired effect.Now,try these simple line of codes:

    //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.

does not work if numberOfLines > 1 What i did made a condition like this-

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

In Swift 4 (Programmatically):

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)

Coming late to the party, but since I had the additional requirement of having one word per line, this one addition did the trick for me:

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

Apple Docs say:

Normally, the label text is drawn with the font you specify in the font property. If this property is set to YES, however, and the text in the text property exceeds the label’s bounding rectangle, the receiver starts reducing the font size until the string fits or the minimum font size is reached. In iOS 6 and earlier, this property is effective only when the numberOfLines property is set to 1.

But this is a lie. A lie I tell you! It's true for all iOS versions. Specifically, this is true when using a UILabel within a UICollectionViewCell for which the size is determined by constraints adjusted dynamically at runtime via custom layout (ex. self.menuCollectionViewLayout.itemSize = size).

So when used in conjunction with adjustsFontSizeToFitWidth and minimumScaleFactor, as mentioned in previous answers, programmatically setting numberOfLines based on word count solved the autoshrink problem. Doing something similar based on word count or even character count might produce a "close enough" solution.


Swift 4, Xcode 9.4.1

The solution that worked for me: I had a label within a collection view cell, and the label text was getting trimmed. Set the attributes as below on Storyboard

Lines = 0
LineBreak = Word Wrap
Set yourlabel's leading and trailing constraint = 0 (using Autolayout)

참고 URL : https://stackoverflow.com/questions/9908334/uilabel-is-not-auto-shrinking-text-to-fit-label-size

반응형