Как усечь NSString на основе графической ширины?

В UILabel существует функциональность для усечения маркировок с помощью различных методов усечения (UILineBreakMode). В Дополнениях NSString UIKit существует схожая функциональность для рисования строк.

Однако я не нашел способа получить доступ к фактической усеченной строке. Там какой-либо другой путь состоит в том, чтобы получить усеченную строку на основе (графической) ширины для данного шрифта?

Я хотел бы иметь категорию на NSString с этим методом:

-(NSString*)stringByTruncatingStringWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode
6
задан Ortwin Gentz 21 February 2014 в 09:02
поделиться

2 ответа

Один из вариантов - пробовать разные размеры путем зацикливания, пока не получите нужную ширину. Т.е. начните с полной строки, если она шире, чем вам нужно, замените последние два символа символом многоточия. Петля, пока она не станет достаточно узкой.

Если вы думаете, что будете работать с длинными строками, вы можете выполнить двоичный поиск до точки усечения, чтобы сделать его немного быстрее.

6
ответ дан 8 December 2019 в 05:21
поделиться
- (NSString*)stringByTruncatingStringWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode {
    NSMutableString *resultString = [[self mutableCopy] autorelease];
    NSRange range = {resultString.length-1, 1};

    while ([resultString boundingRectWithSize:CGSizeMake(FLT_MAX, FLT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attributes context:nil].size.width > width) {
        // delete the last character
        [resultString deleteCharactersInRange:range];
        range.location--;
        // replace the last but one character with an ellipsis
        [resultString replaceCharactersInRange:range withString:truncateReplacementString];
    }
    return resultString;
}

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

17
ответ дан 8 December 2019 в 05:21
поделиться