Как вписать предложение в прямоугольник заданного размера?

Добрый день!

Мне требуется вывести предложение (sentence) в несколько строк, перенося по словам и уменьшив шрифт таким образом, чтобы все предложение поместилось в заданный максимальный размер. При этом хочется, чтобы размер шрифта был максимально возможным.

Ниже код которым вывожу предложение в прямоугольник:
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];
  • Вопрос задан
  • 3207 просмотров
Решения вопроса 1
andreys75
@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];


 вот этот код стал решением проблемы
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
morozovdenis
@morozovdenis
даже в простом случае с моноширинным шрифтом нельзя написать формулу которая будет вычислять размер шрифта, перенос по словам усложняет. остаётся только перебор по размеру шрифта

у вас строки могут быть любые? или они предзабиты(заголовки например)?
Ответ написан
corristo
@corristo
UILabel делает то что вам нужно из коробки:
label.attributedString = yourStirng;
label.adjustsFontSizeToFitWidth = YES;
label.minimumScaleFactor = 0.5; //разшаем умеьншение размера шрифта максимум в 2 раза
CGSize boundedStringSize = [label sizeThatFits:yourBoundsSize];


Правда на iOS 6 это, похоже, будет работать только для однострочного label :(
Ответ написан
kaspartus
@kaspartus
В iOS7 при помощи Text Kit это можно сделать.

Краткая история: Есть книжка iOS 7 by tutorials - там делают приложение-книжку, много текста, есть картинки, текст форматирован. Возникают логичные вопросы: "Как разбивать его на страницы? Как узнать сколько текста уместилось на странице?" - ответ прост, у NSLayoutManager есть метод glyphRangeForTextContainer: он возвращает кол-во символов в контейнере.

Потому можем сделать так:
1. Создаем NSTextStorage, скармливаем ему NSAttributedString.
2. Создаем NSLayoutManager, отдаем его textStorage'y при помощи addLayoutManager
3. Создаем NSTextContainer, отдаем его layoutManager'у
4. Вот тут уже можем при помощи glyphRangeForTextContainer: узнать поместился текст или нет. Меняем шрифт, считаем еще раз. Можно например начать с 10 и расти вверх, как вылезли - взяли предыдущий размер.
5. Создаем UITextView при помощи initWithFrame:textContainer:
6. Успех

Метод костыльный + overkill, работает только на iOS7+. Возможно при помощи textKit можно сделать все изящней, а возможно можно все аккуратно обойти.
Ответ написан
andreys75
@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


увы вот этот код не заработал. Если места достаточно, то он переносит по словам, но если места недостаточно, то шрифт не уменьшается а просто обрезается кусок
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы