I use a table view to show a list of books, where each cell has a UILabel
that shows the book\'s name and another UILabel
the shows the book\'s aut
This answer is based on https://stackoverflow.com/a/30813691/2123122. Here is the sample code.
@interface CustomLabel()
@property (nonatomic, retain) NSLayoutManager *layoutManager;
@property (nonatomic, retain) NSTextContainer *textContainer;
@property (nonatomic, retain) NSTextStorage *textStorage;
@end
@implementation CustomLabel
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self configureTextkitStack];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self configureTextkitStack];
}
return self;
}
- (void)configureTextkitStack {
_textContainer = [[NSTextContainer alloc] init];
_textContainer.lineFragmentPadding = 0;
_textContainer.maximumNumberOfLines = self.numberOfLines;
_textContainer.lineBreakMode = self.lineBreakMode;
_textContainer.widthTracksTextView = YES;
_layoutManager = [[NSLayoutManager alloc] init];
[_layoutManager addTextContainer:self.textContainer];
[_textContainer setLayoutManager:self.layoutManager];
_textStorage = [[NSTextStorage alloc] init];
[_textStorage addLayoutManager:self.layoutManager];
[self.layoutManager setTextStorage:_textStorage];
}
- (NSRange)rangeForTokenInsertion {
self.textContainer.size = self.bounds.size;
if (self.attributedText.length > 0 ){
[self.textStorage setAttributedString:[[NSMutableAttributedString alloc]initWithAttributedString:self.attributedText]];
}
if (self.text.length == 0) {
return NSMakeRange(NSNotFound, 0);
}
NSInteger glyphIndex = [self.layoutManager glyphIndexForCharacterAtIndex:self.textStorage.length - 1];
NSRange range = [self.layoutManager truncatedGlyphRangeInLineFragmentForGlyphAtIndex:glyphIndex];
return range;
}
Now you can use this as follows:
NSRange range = [self.label rangeForTokenInsertion];
NSString *token = @"...+2 authors";
if (range.location != NSNotFound ) {
range.length += token.length;
range.location -= token.length;
}
if (range.location != NSNotFound) {
NSString *finalString = [self.label.text stringByReplacingCharactersInRange:range withString:token];
self.label.text = finalString;
}
I have created a UILabel subclass called ResponsiveLabel which handles custom truncation token as well as applying styles to patterns like userhandles, URLs, hashtags etc.