I can create a multi-line NSAttributedString
by using escaped new-line characters (@"\n"
). With iOS 7, I can now embed a UIImage
inside attributed strings (via NSTextAttachment
).
I have noticed that whenever I set the attributedText
of a UILabel
to a multi-line attributed string with an embedded image, the number of lines actually displayed is inversely proportional to the height of the label. For example, when the height of the label is 80, two lines appear; when the height is around 100, only the second line appears; when the height is about 130, nothing appears.
This problem occurred while trying to position multiple UILabels side-by-side inside a UITableViewCell
and having the labels grow (vertically) with the cell height.
Can anyone explain why this is happening? Does anyone know workarounds that don't involve making the UILabel smaller?
Sample code:
@implementation SOViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableAttributedString *text1 = [[NSMutableAttributedString alloc] init];
[text1 appendAttributedString:[[NSAttributedString alloc] initWithString:@"Line 1\n"]];
[text1 appendAttributedString:[[NSAttributedString alloc] initWithString:@"Line 2"]];
UIImage *image = [UIImage imageNamed:@"17x10"]; //some PNG image (17px by 10px)
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = image;
attachment.bounds = CGRectMake(0, 0, image.size.width, image.size.height);
NSMutableAttributedString *text2 = [[NSMutableAttributedString alloc] init];
[text2 appendAttributedString:[[NSAttributedString alloc] initWithString:@"Line 1\n"]];
[text2 appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
[text2 appendAttributedString:[[NSAttributedString alloc] initWithString:@"Line 2"]];
CGFloat margin = 20;
//shows both lines when height == 80
//shows line 2 when 90 <= height <= 120
//shows nothing when height == 130
CGFloat height = ???;
CGFloat width = 200;
UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(margin, margin, width, height)];
UILabel *label2 = [[UILabel alloc] initWithFrame:CGRectMake(margin, margin + height, width, height)];
[self.view addSubview:label1];
[self.view addSubview:label2];
label1.backgroundColor = [UIColor orangeColor];
label2.backgroundColor = [UIColor blueColor];
label2.textColor = [UIColor whiteColor];
label1.numberOfLines = 0;
label2.numberOfLines = 0;
label1.attributedText = text1;
label2.attributedText = text2;
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(margin + width, margin + height, image.size.width, image.size.height);
[self.view addSubview:imageView];
}
@end
... Put this in the default view controller of a "Single View Application". (You can pick your own image.)