使用 CoreText 绘制时不显示 NSTextAttachment 图像

NSTextAttachment image not showing when drawing using CoreText

由于某些原因,我无法在使用核心文本时获取 NSTextAttachment 图像来绘制,尽管将 NSAttributedString 添加到 UILabel 时相同的图像可以正常显示。

在 iOS 上,此渲染将为 NSTextAttachment 提供空白空间,对于 OS X,将为每个 NSTextAttachment 渲染一个占位符 [OBJECT] 方形图像。为了使用 CoreText 渲染图像,是否还需要做其他事情?

渲染代码:

CGFloat contextHeight = CGBitmapContextGetHeight(context);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)_attributedString);
CGPathRef path = CGPathCreateWithRect(CGRectMake(rect.origin.x,
                                                 contextHeight - rect.origin.y - rect.size.height,
                                                 rect.size.width,
                                                 rect.size.height), NULL);
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
CFRelease(framesetter);
CGPathRelease(path);
CGContextSaveGState(context);
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0.0f, contextHeight);
CGContextScaleCTM(context, 1.0f, -1.0f);
CTFrameDraw(frame, context);
CGContextRestoreGState(context);
CFRelease(frame);

原因很简单,NSTextAttachment 仅适用于将 NSAttributedString 渲染为 UIView/NSView。它不能用于呈现为常规 CGContext。

解决问题的方法有两种:

  1. 创建一个 UILabel、CATextLayer 或类似的对象,并将其渲染到图形上下文中。
  2. 使用CTRunDelegate在文本中打空,然后循环遍历所有要渲染的行,手动将图像直接绘制到CGContext中。具体方法在这里:https://www.raywenderlich.com/4147/core-text-tutorial-for-ios-making-a-magazine-app。如果你沿着这条路走下去,预计会有很多工作,但它确实有效。