UILabel không tự động thu nhỏ văn bản để vừa với kích thước nhãn


119

Tôi gặp sự cố kỳ lạ này và tôi đang giải quyết nó hơn 8 giờ rồi .. Tùy thuộc vào tình huống, tôi phải tính toán UILabelskích thước động,
ví dụ:
tôi UIViewControllernhận được một sự kiện và tôi thay đổi UILabelskích thước. từ lớn hơn đến nhỏ hơn. Kích thước của tôi UILabelnhỏ hơn và tôi nhận được kích thước cần thiết chính xác, nhưng văn bản trong của tôi UILabelvẫn giữ nguyên, cùng kích thước phông chữ và v.v. Tôi cần phông chữ nhỏ hơn, để toàn bộ văn bản vừa với UILabel. Vì vậy, câu hỏi là làm thế nào để làm cho văn bản phù hợp với nhãn của tôi autoshrinkinghoặc tương tự như vậy?

Trong tôi xib, UILabels autoshrinkđược kiểm tra, cũng số dòng được đặt thành 0, và cũng có chuỗi của tôi có ký tự dòng mới (\ n), và tôi đã chọn lineBreakMode tới wordwrap. Có thể có ai đang ở trong hoàn cảnh giống như tôi bây giờ, và có thể giúp tôi? Tôi thực sự đánh giá cao việc đó.

Cảm ơn trước!

CHỈNH SỬA: UILabel kích thước phông chữ tối thiểu được đặt thành 10


kích thước tối thiểu của phông chữ của bạn cho lable bạn đặt, vui lòng thêm vào.
AJPatel

Câu trả lời:


159

Trong trường hợp bạn vẫn đang tìm kiếm giải pháp tốt hơn, tôi nghĩ đây là điều bạn muốn:

Giá trị Boolean cho biết có nên giảm kích thước phông chữ để vừa với chuỗi tiêu đề vào hình chữ nhật giới hạn của nhãn hay không (thuộc tính này chỉ có hiệu lực khi thuộc numberOfLinestính được đặt thành 1).

Khi đặt thuộc tính này, cũng minimumScaleFactorPHẢI được đặt (mặc định tốt là 0,5).

Nhanh

var adjustsFontSizeToFitWidth: Bool { get set }

Objective-C

@property(nonatomic) BOOL adjustsFontSizeToFitWidth;

Giá trị Boolean cho biết liệu khoảng cách giữa các chữ cái có được điều chỉnh để vừa với chuỗi trong hình chữ nhật giới hạn của nhãn hay không.

Nhanh

var allowsDefaultTighteningForTruncation: Bool { get set }

Objective-C

@property(nonatomic) BOOL allowsDefaultTighteningForTruncation;

Nguồn .


18
Là một phụ chú, minimumFontSizekhông được dùng nữa trong iOS 6.0. Sử dụng minimumScaleFactorthay thế.
lester,

14
Có, tự động thu nhỏ không hoạt động cho nhiều dòng trong UILabel. Hãy thử tưởng tượng điều này: bạn có văn bản với nhiều dòng, bạn muốn thu nhỏ nó lại để nó "vừa vặn" với chiều rộng. Vì vậy, nó nên thu nhỏ toàn bộ văn bản để vừa trong một dòng, hay các từ vẫn ở trên cùng một dòng và thu nhỏ để vừa với mỗi chiều rộng? Trường hợp sau là trường hợp phổ biến nhất, nhưng đừng quên rằng các từ cũng được thiết lập để tự sắp xếp thành nhiều dòng. Ngay cả khi tính năng tự động sắp xếp văn bản bị tắt, bạn sẽ phải đối mặt với việc mỗi dòng văn bản có kích thước phông chữ khác nhau, vì không phải mọi từ đều vừa với chiều rộng.
lester

2
Tôi nghĩ câu trả lời này với một Category ở đây là khá tốt, nó thậm chí có thể là những gì bạn đã triển khai. Đây chắc chắn là điều gì đó còn thiếu trong Apple API, hoặc có thể họ không thấy thu nhỏ nên là trường hợp sử dụng phổ biến cho nhiều dòng văn bản tĩnh .
lester

1
Vâng, đó là một điểm tốt, nhưng dù sao, tôi nghĩ nếu tôi đặt số dòng thành 0, đó là một tuyên bố rõ ràng rằng có thể có một hoặc nhiều dòng. Và autoshrink có thể bị xấu đi bởi số dòng mà tôi đoán .. Nhưng dù sao, cảm ơn vì đã xóa mọi thứ. Tôi nghĩ tôi đã làm điều gì đó sai trái. Một phân loại là một ý tưởng hay, tôi đoán tôi sẽ làm điều đó trong dự án khác, nơi tôi sẽ cần nó. Đánh giá cao sự giúp đỡ của bạn, chúc may mắn;)
Lukas

4
@lester Nó sẽ thu nhỏ lại để toàn bộ văn bản có thể nhìn thấy được với số dòng được khai báo cho nhãn với kích thước hiện tại của nó. Nó không cần phải cố gắng làm cho mỗi dòng có một kích thước khác nhau. Tôi thực sự ngạc nhiên vì nó không thể hiểu được điều này. Vì vậy, nếu tôi có một chuỗi dài (có khả năng) để hiển thị, tôi có thể có nhiều dòng hoặc đặt nó tự động kích thước, không phải cả hai. Thật đáng yêu.
defos1

125

Đây là cách tôi Autoshrinklàm việc với UILabel (đặc biệt đối với chiều cao của phông chữ nhãn phù hợp trong thiết bị 4s từ Bảng phân cảnh 6s Plus) trong iOS 9.2, Xcode 7.2 ...

nhập mô tả hình ảnh ở đây

  • Số dòng là 0
  • Ngắt dòng: Clip
  • Autoshrink: Tỷ lệ phông chữ tối thiểu 0,25

15
Đây là 3 thành phần cần thiết để một nhãn thực sự co lại, tôi đã thiếu cài đặt ngắt dòng clip. Ngoài ra, nếu nó liền kề với các nhãn khác (cũng có thể tự động thu nhỏ) thì ưu tiên nén / ôm cần được đặt hoặc đưa ra các ràng buộc về chiều rộng hoặc chiều cao rõ ràng. Đây phải là câu trả lời hiện được chấp nhận.
Korey Hinton,

3
Số dòng đã làm điều đó cho tôi! Cảm ơn bạn
Michael

Đảm bảo rằng nhãn của bạn có tất cả các ràng buộc, đặc biệt là đầu và cuối.
Mashhadi

2
Tôi đã thử với các tùy chọn tương tự trong Xcode8 và không thấy hoạt động. Xin vui lòng giúp tôi nếu bất cứ ai có ý tưởng về điều này.
Ganesh

75

minimumFontSize không được dùng nữa trong iOS 6.

Vì vậy, sử dụng minimumScaleFactorthay vì minmimumFontSize.

lbl.adjustsFontSizeToFitWidth = YES
lbl.minimumScaleFactor = 0.5

Swift 5

lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5

Trả lời tốt. Đã giải quyết vấn đề của tôi. Cảm ơn
Abdul Yasin

1
@AntonMatosov, không, không!
Iulian Onofrei

2
Vâng, nó (bây giờ) - nếu bạn cũng thiết lập các ngắt dòng để Truncate Tail thay vì Word Wrap ...
TheEye

21

cũng là giải pháp của tôi là boolean label.adjustsFontSizeToFitWidth = YES; NHƯNG. Bạn phải trong giao diện Builder, chuyển Word Wrapping thành " CLIP ". Sau đó tự động rắc Nhãn. Cái này rất quan trọng.


3
Chỉ khi tôi thay đổi từ "Word Wrap" thành "Clip" thì Autoshrink mới hoạt động cho tôi.
NicJ

Khi tôi thay đổi word wrap thành clip, tôi thực sự có thể làm cho nó thay đổi kích thước trong một nhãn không có dòng nào. Thật tuyệt nếu điều này được ghi lại.
Được chỉ

12

Trong Swift 3 (Lập trình), tôi phải làm điều này:

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

5

Bạn có thể viết như

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

Bạn có thể tính toán số dòng như vậy

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

Hy vọng điều này sẽ giúp bạn :-) chờ trả lời của bạn


vì vậy nếu đặt số dòng cho nhãn của tôi, văn bản sẽ tự động nhăn lại sau đó?
Lukas

nếu nội dung của bạn nằm ngoài chiều rộng sau đó nó sẽ mất nextline
Birju

này, tôi đã làm như bạn đề nghị, nhưng nó không hoạt động, tại sao số dòng sẽ giúp tôi?
Lukas

bạn là đúng tôi đã cố gắng của nó không hữu ích, nhưng tôi tìm thấy giải pháp cho bạn làm như vậy câu trả lời tiếp theo của tôi
Birju

lbl.adjustsFontSizeToFitWidth = CÓ; Đã làm cho tôi!
Nhà phát triển

4

Cuối cùng thì tôi cũng không tìm thấy câu trả lời của mình. Và tôi nghĩ rằng autoshrink không hoạt động cho nhiều dòng. Tôi đã kết thúc bằng cách sử dụng đề xuất trong liên kết này: autoshrink trên UILabel có nhiều dòng

Các giải pháp là tính toán chiều cao văn bản ở chiều rộng nhất định và nếu văn bản lớn hơn, thu nhỏ kích thước phông chữ và sau đó làm lại như vậy cho đến khi chiều cao bằng hoặc nhỏ hơn kích thước bạn cần.

Tôi không hiểu tại sao điều này rất khó thực hiện. Nếu tôi có thiếu sót gì đó, mong mọi người sửa cho tôi :)


Theo các câu trả lời khác ở đây, điều quan trọng còn thiếu là bạn cần đặt Word Wrapping thành "Clip". Nó phản trực quan, nhưng điều này là bắt buộc để UILabel tự động thu nhỏ theo cách bạn muốn. Điều này hoạt động với UILabel nhiều dòng.
Duncan Babbage,

4

Điều này dành cho Swift 3 chạy Xcode 8.2.1 (8C1002)

Giải pháp tốt nhất mà tôi đã tìm thấy là đặt chiều rộng cố định trong Bảng phân cảnh hoặc IB của bạn trên nhãn. Đặt ràng buộc của bạn với ràng buộc đối với lề. Trong viewDidLoad của bạn, hãy thêm các dòng mã sau:

override func viewDidLoad() {
            super.viewDidLoad()

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

ràng buộc nhãn đối với lề

cố định độ rộng nhãn ràng buộc đối với lề

người kiểm tra thuộc tính

Điều này hoạt động như một sự quyến rũ và nó không tràn sang một dòng mới và thu nhỏ văn bản để vừa với chiều rộng của nhãn mà không có bất kỳ vấn đề kỳ lạ nào và hoạt động trong Swift 3.


4

Đó là một câu hỏi tuyệt vời, bởi vì bây giờ có cảm giác đó sẽ là một phần của UIKitchức năng tích hợp sẵn hoặc một khuôn khổ liên quan. Đây là một ví dụ trực quan tốt về câu hỏi:

Hoạt ảnh thay đổi kích thước phông chữ

Không có cách nào dễ dàng xung quanh nó, nhưng nó chắc chắn có thể. Một cách để thực hiện việc này là thử theo chương trình các kích thước phông chữ khác nhau cho đến khi bạn tìm thấy kích thước phông chữ phù hợp hợp lý gần với giới hạn của chế độ xem. Bạn có thể thực hiện điều này với boundingRect()chức năng của NSStringhoặc NSAttributedString. Ví dụ:

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

Bạn có thể thực hiện tìm kiếm nhị phân để hiệu quả hơn so với cách tiếp cận vũ phu hoàn toàn. Ngoài ra còn có một số cân nhắc liên quan hơn một chút, bao gồm gói từ chính xác và hiệu suất bộ nhớ đệm phông chữ iOS, nếu bạn đang tìm kiếm thứ gì đó thực sự mạnh mẽ.

Nếu bạn chỉ quan tâm đến việc hiển thị văn bản trên màn hình một cách dễ dàng, tôi đã phát triển một triển khai mạnh mẽ trong Swift, mà tôi cũng đang sử dụng trong một ứng dụng sản xuất. Đó là một UIViewlớp con với khả năng chia tỷ lệ phông chữ tự động, hiệu quả cho bất kỳ văn bản đầu vào nào, bao gồm nhiều dòng. Để sử dụng nó, bạn chỉ cần làm điều gì đó như:

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

Đó là nó! Bạn có thể tìm thấy nguồn đầy đủ tại đây: https://github.com/FlickType/AccessibilityKit

Hi vọng điêu nay co ich!


1
Tháng 11 năm 2018: Xuất hiện FlickType và AccessibilityKit đã chuyển sang chế độ riêng tư hoặc bị xóa.
Chris Paveglio

3

Trong iOS 9, tôi chỉ cần:

  1. Thêm các ràng buộc từ bên trái và bên phải của nhãn vào superview.
  2. Đặt chế độ ngắt dòng thành cắt trong IB.
  3. Đặt số dòng là 1 trong IB.

Ai đó đã đề xuất đặt số dòng thành 0, nhưng đối với tôi, điều này chỉ làm cho nhãn chuyển sang nhiều dòng ...


Điều này đã làm các mẹo cho tôi. Tôi vừa chọn a UILabelvà a UITextFieldtrong một ô tĩnh và nhấp vào "Giải quyết vấn đề tự động thanh toán" và "Thêm các ràng buộc còn thiếu". Mọi thứ đều xếp hàng, nhưng Autoshrink cần biết khoảng cách đến nhãn, điều mà "Thêm các ràng buộc bị thiếu" không thêm ràng buộc.
Adrian

2

Tôi nghĩ bạn có thể viết mã dưới đây sau khi cấp phát 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];

Nó đang làm việc với tôi tốt. Sử dụng nó


1
cảm ơn, nhưng điều này sẽ không tính toán hoặc thu nhỏ phông chữ đến mức tối thiểu cần thiết như tôi hiểu, và cũng là lý do tại sao phông chữ tối thiểu của bạn lớn hơn bình thường?
Lukas

2

Hai năm trôi qua, và vấn đề này vẫn còn ...

Trong iOS 8 / XCode 6.1, đôi khi tôi thấy rằng UILabel(được tạo trongUITableViewCell , với tính năng Tự động thanh toán được bật và các ràng buộc linh hoạt để nó có nhiều không gian) sẽ không tự thay đổi kích thước để vừa với chuỗi văn bản.

Giải pháp, như những năm trước, là cài đặt văn bản, sau đó gọi điện sizeToFit.

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

(Thở dài.)


1

Đây là cách thực hiện. Giả sử thông báo sau Nhãn là nhãn bạn muốn để có hiệu ứng mong muốn. Bây giờ, hãy thử các dòng mã đơn giản sau:

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

này, cảm ơn câu trả lời của bạn, nhưng tôi không cần tính chiều cao của nhãn, tôi có kích thước cố định và tùy thuộc vào đó phông chữ của tôi phải nhỏ hơn nếu cần.
Lukas

1

không hoạt động nếu numberOfLines > 1 Điều tôi đã làm đưa ra một điều kiện như thế này-

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

0

Đến bữa tiệc muộn, nhưng vì tôi có yêu cầu bổ sung là phải có một từ trên mỗi dòng, nên việc bổ sung này đã thực hiện mẹo cho tôi:

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

Apple Docs nói:

Thông thường, văn bản nhãn được vẽ bằng phông chữ bạn chỉ định trong thuộc tính phông chữ. Tuy nhiên, nếu thuộc tính này được đặt thành CÓ và văn bản trong thuộc tính văn bản vượt quá hình chữ nhật giới hạn của nhãn, bộ thu sẽ bắt đầu giảm kích thước phông chữ cho đến khi chuỗi phù hợp hoặc đạt đến kích thước phông chữ tối thiểu. Trong iOS 6 trở về trước, thuộc tính này chỉ có hiệu lực khi thuộc tính numberOfLines được đặt thành 1.

Nhưng đây là một lời nói dối. Tôi nói dối bạn! Nó đúng với tất cả các phiên bản iOS. Cụ thể, điều này đúng khi sử dụng UILabeltrong một UICollectionViewCellkích thước mà kích thước được xác định bởi các ràng buộc được điều chỉnh động trong thời gian chạy thông qua bố cục tùy chỉnh (ví dụ:self.menuCollectionViewLayout.itemSize = size :).

Vì vậy, khi được sử dụng kết hợp với adjustsFontSizeToFitWidthminimumScaleFactor, như đã đề cập trong các câu trả lời trước, cài đặt theo chương trình numberOfLinesdựa trên số lượng từ đã giải quyết được vấn đề autoshrink. Làm điều gì đó tương tự dựa trên số từ hoặc thậm chí số ký tự có thể tạo ra giải pháp "đủ gần".


0

Trong Swift 4 (Lập trình):

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

Swift 4, Xcode 9.4.1

Giải pháp phù hợp với tôi: Tôi có một nhãn trong ô chế độ xem bộ sưu tập và văn bản nhãn đang được cắt bớt. Đặt các thuộc tính như bên dưới trên Storyboard

Lines = 0
LineBreak = Word Wrap
Set yourlabel's leading and trailing constraint = 0 (using Autolayout)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.