20

NSAttributedStringエスケープされた改行文字 ( ) を使用して複数行を作成できます@"\n"UIImageiOS 7 では、属性付き文字列の中に ( 経由で) を埋め込むことができるようになりましたNSTextAttachment

埋め込み画像を含む複数行の属性付き文字列にattributedTextaを設定すると、実際に表示される行数がラベルの高さに反比例することに気付きました。たとえば、ラベルの高さが 80 の場合、2 本の線が表示されます。高さが 100 前後の場合、2 行目のみが表示されます。高さが約 130 の場合、何も表示されません。UILabel

この問題は、複数の UILabel を a 内に並べて配置しようとしたときUITableViewCellに、セルの高さに合わせてラベルが (垂直方向に) 大きくなるときに発生しました。

なぜこれが起こっているのか誰でも説明できますか?UILabel を小さくすることを伴わない回避策を知っている人はいますか?


サンプルコード:

@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

...これを「Single View Application」のデフォルトView Controllerに入れます。(お好きな画像をお選びいただけます。)

4

4 に答える 4

1

このバグの別の回避策を見つけました。これは、別の回答として提供している以前の回答とは十分に異なります。ラベルに独自の高さを設定させます。

このコードでは、固定幅の制約を持つラベルから高さの制約を削除し、それを高さより大きい制約に置き換えています (同じ結果を達成する方法は他にもあるはずです)。

[self.lab removeConstraint:self.labelHeight];
[self.lab addConstraint:
 [NSLayoutConstraint constraintWithItem:self.lab 
 attribute:NSLayoutAttributeHeight 
 relatedBy:NSLayoutRelationGreaterThanOrEqual 
 toItem:nil attribute:0 multiplier:1 constant:20]];

そのラベルは、私が投げたすべての属性付き文字列を正しく表示します! もちろん、文字列の自動垂直センタリングは失われますが、それがバグの全体的な原因であるため、失われることはそれほどひどいことではありません。

于 2013-10-23T14:54:24.733 に答える
0

boundingRectWithSize メソッドを使用して、テキストの実際の高さを取得しようとしましたか:

NSAttributedString *text;
CGFloat width = 200;
CGRect rect = [text boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil];
CGFloat height = rect.size.height;
于 2013-10-15T12:01:01.410 に答える