A
A
andreys752014-04-20 22:00:14
Objective-C
andreys75, 2014-04-20 22:00:14

How to fit a sentence into a rectangle of a given size?

Good afternoon!
I need to display a sentence (sentence) in several lines, wrapping words and reducing the font so that the entire sentence fits into the specified maximum size. At the same time, I want the font size to be as large as possible.
Below is the code that displays the sentence in a rectangle:

NSAttributedString *sentence = [[NSAttributedString alloc] initWithString:@" Предложение? которое надо вписать в прамоугольник" attributes:@{NSFontAttributeName: wordsFont,NSBackgroundColorAttributeName:[UIColor yellowColor]}];
    
    
    CGRect sentenceBounds;
    sentenceBounds.size = [sentence size];
    CGSize neededSize = CGSizeMake(MAX_WIDTH, MAX_Height);
    sentenceBounds.size = neededSize;

    if (sentenceBounds.size.width > MAX_WIDTH) {
        NSLog(@"Problem with sentence width");
    }
    sentenceBounds.origin = CGPointMake(0, 0);
    DLog(@"%@", NSStringFromCGRect(sentenceBounds));
    [sentence drawInRect:sentenceBounds];

Answer the question

In order to leave comments, you need to log in

[[+comments_count]] answer(s)
A
andreys75, 2014-04-21
@andreys75

UILabel *label = [UILabel new];
    label.adjustsFontSizeToFitWidth = YES;
    label.numberOfLines = 0;
    label.font = wordsFont;
    label.attributedText = [[NSAttributedString alloc] initWithString:self.card.firstWordSentence];
    label.frame = CGRectMake(10, 10, CARD_WIDTH*0.9, CARD_HEIGHT*0.2); //set desired frame here;
    [self addSubview:label];

 this code is the solution to the problem

D
Denis Morozov, 2014-04-21
@morozovdenis

even in the simple case of a monospaced font, it is impossible to write a formula that will calculate the font size, word wrap complicates. it remains only to search by font size
, can you have any lines? or are they preloaded (headlines for example)?

C
corristo, 2014-04-21
@corristo

UILabel does what you need out of the box:

label.attributedString = yourStirng;
label.adjustsFontSizeToFitWidth = YES;
label.minimumScaleFactor = 0.5; //разшаем умеьншение размера шрифта максимум в 2 раза
CGSize boundedStringSize = [label sizeThatFits:yourBoundsSize];

True on iOS 6 this seems to only work for a single line label :(

K
kaspartus, 2014-04-21
@kaspartus

In iOS7, you can do this with Text Kit.
Brief history: There is a book iOS 7 by tutorials - they make a book app, a lot of text, there are pictures, the text is formatted. Logical questions arise: "How to paginate it? How to find out how much text fits on a page?" - the answer is simple, NSLayoutManager has a glyphRangeForTextContainer method : it returns the number of characters in the container.
Therefore, we can do this:
1. Create an NSTextStorage , feed it an NSAttributedString .
2. Create NSLayoutManager , give it to textStorage'y using addLayoutManager
3. CreateNSTextContainer , we give it to layoutManager
4. Here we can already use glyphRangeForTextContainer to find out if the text fits or not. Change the font, count again. For example, you can start with 10 and grow up, as you got out - they took the previous size.
5. Create UITextView using initWithFrame:textContainer:
6. Success
The crutch + overkill method, works only on iOS7+. Perhaps with the help of textKit you can make everything more elegant, or maybe you can get around everything neatly.

A
andreys75, 2014-04-21
@andreys75

UILabel *sentence = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, CARD_WIDTH*0.9, CARD_HEIGHT/4)]; //создаем объект, который будет являться нашим View
    sentence.textColor = [UIColor blackColor]; //задаем цвет текста
    sentence.backgroundColor = [UIColor yellowColor];
    sentence.lineBreakMode = NSLineBreakByWordWrapping;
    sentence.numberOfLines = 0;
    sentence.font = wordsFont;
    sentence.text = self.card.firstWordSentence; //какой-нибудь текст
    

    sentence.adjustsFontSizeToFitWidth = YES; //можно сделать, чтобы текст автоматически уменьшался, если не помещается, при этом увеличиваться больше заданного размера (или системного, если размер не задан) текст не будет
    
    
   CGSize boundedStringSize = [sentence sizeThatFits:CGSizeMake(CARD_WIDTH, CARD_HEIGHT/4)];
    
    
    [self addSubview:sentence]; //добавляем наш текст в иерархию View

Alas, this code didn't work. If there is enough space, then it wraps by word, but if there is not enough space, then the font is not reduced, but a piece is simply cut off

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question