139

NSTextAttachment属性付きの文字列に画像を追加して、垂直方向の中央に配置したいと思います。

次のコードを使用して文字列を作成しました。

NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:DDLocalizedString(@"title.upcomingHotspots") attributes:attrs];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = [[UIImage imageNamed:@"help.png"] imageScaledToFitSize:CGSizeMake(14.f, 14.f)];
cell.textLabel.attributedText = [str copy];

ただし、画像はセルの上部に位置合わせされているように見えますtextLabel

テキスト添付オフセットの問題のスクリーンショット

添付ファイルが描画される四角形を変更するにはどうすればよいですか?

4

10 に答える 10

115

試してみてください- [NSTextAttachment bounds]。サブクラス化は必要ありません。

コンテキストUILabelとして、添付画像として使用するために をレンダリングし、次のように境界を設定して attachment.bounds = CGRectMake(0, self.font.descender, attachment.image.size.width, attachment.image.size.height)います。ラベル画像内のテキストのベースラインと属性付き文字列内のテキストを必要に応じて並べます。

于 2015-02-05T22:22:36.237 に答える
65

rect をサブクラス化NSTextAttachmentしてオーバーライドすることで変更できますattachmentBoundsForTextContainer:proposedLineFragment:glyphPosition:characterIndex:。例:

- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex {
    CGRect bounds;
    bounds.origin = CGPointMake(0, -5);
    bounds.size = self.image.size;
    return bounds;
}

それは完璧な解決策ではありません。Y 原点を「目で」把握する必要があり、フォントやアイコンのサイズを変更すると、おそらく Y 原点を変更したくなるでしょう。しかし、アイコンを別の画像ビューに配置することを除いて、より良い方法を見つけることができませんでした (これには独自の欠点があります)。

于 2014-09-29T19:32:43.873 に答える
64

私はこれに対する完璧な解決策を見つけましたが、私にとっては魅力のように機能しますが、自分で試してみる必要があります (おそらく、定数はデバイスの解像度に依存し、おそらく何でもあります;)

func textAttachment(fontSize: CGFloat) -> NSTextAttachment {
    let font = UIFont.systemFontOfSize(fontSize) //set accordingly to your font, you might pass it in the function
    let textAttachment = NSTextAttachment()
    let image = //some image
    textAttachment.image = image
    let mid = font.descender + font.capHeight
    textAttachment.bounds = CGRectIntegral(CGRect(x: 0, y: font.descender - image.size.height / 2 + mid + 2, width: image.size.width, height: image.size.height))
    return textAttachment
}

動作し、ぼやけてはいけません (おかげでCGRectIntegral)

于 2015-12-01T18:17:04.757 に答える
42

どうですか:

CGFloat offsetY = -10.0;

NSTextAttachment *attachment = [NSTextAttachment new];
attachment.image = image;
attachment.bounds = CGRectMake(0.0, 
                               offsetY, 
                               attachment.image.size.width, 
                               attachment.image.size.height);

サブクラス化は不要

于 2015-04-29T21:11:08.103 に答える
2

私の場合、 sizeToFit() を呼び出すことが役に立ちました。スイフト5.1で

カスタム ラベルの内側:

func updateUI(text: String?) {
    guard let text = text else {
        attributedText = nil
        return
    }

    let attributedString = NSMutableAttributedString(string:"")

    let textAttachment = NSTextAttachment ()
    textAttachment.image = image

    let sizeSide: CGFloat = 8
    let iconsSize = CGRect(x: CGFloat(0),
                           y: (font.capHeight - sizeSide) / 2,
                           width: sizeSide,
                           height: sizeSide)
    textAttachment.bounds = iconsSize

    attributedString.append(NSAttributedString(attachment: textAttachment))
    attributedString.append(NSMutableAttributedString(string: text))
    attributedText = attributedString

    sizeToFit()
}
于 2020-02-11T14:57:46.737 に答える
0

境界の高さには -lineFrag.size.height/5.0 を使用してください。これにより、画像が正確に中央に配置され、すべてのサイズのフォントのテキストに揃えられます

override func attachmentBoundsForTextContainer(textContainer: NSTextContainer, proposedLineFragment lineFrag: CGRect, glyphPosition position: CGPoint, characterIndex charIndex: Int) -> CGRect
{
    var bounds:CGRect = CGRectZero

    bounds.size = self.image?.size as CGSize!
    bounds.origin = CGPointMake(0, -lineFrag.size.height/5.0);

    return bounds;
}
于 2015-03-16T05:40:59.267 に答える