2010-02-15 10 views
6

W UILabel istnieje funkcjonalność do obcinania etykiet przy użyciu różnych technik skracania (UILineBreakMode). W NSString UIKit Additions istnieje podobna funkcjonalność do rysowania ciągów.Jak skrócić NSString na podstawie szerokości graficznej?

Jednak nie znalazłem sposobu, aby uzyskać dostęp do faktycznego obciętego napisu. Czy istnieje inny sposób na uzyskanie obciętego łańcucha na podstawie szerokości (graficznej) danej czcionki?

Chciałbym mieć kategorię na NSString z tą metodą:

-(NSString*)stringByTruncatingStringWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode 

Odpowiedz

6

Jedną z opcji jest próbowanie różnych rozmiarach poprzez zapętlenie aż do uzyskania właściwej szerokości. To znaczy. zacznij od pełnego ciągu, jeśli jest szerszy niż to, czego potrzebujesz, zamień dwa ostatnie znaki na znak wielokropka. Pętla, aż będzie wystarczająco wąska.

Jeśli myślisz, że będziesz pracować z długimi łańcuchami, możesz wyszukiwać binarnie w kierunku punktu skracania, aby był on nieco szybszy.

+0

Dzięki Uli, dobry pomysł. Działa jak marzenie. Zobacz kod w innym komentarzu. –

17
- (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; 
} 

Należy pamiętać, że od czasu iOS 6 ta metoda nie jest już bezpieczna w przypadku wątków w tle.

+0

Prawdopodobnie powinien zostać zaktualizowany za pomocą metody iOS - boundingRectWithSize: options: attributes: context :, z powodu przestarzałości. – skyylex

+0

@skyylex rzeczywiście. Gotowe. –

Powiązane problemy