NSAttributedString中UITextView的自动调整图片大小

4

我正在尝试使用UITextView显示包含图像的rtfd文档。问题是,图像重叠在UITextView的边框上 - 它的宽度更大。我需要将此图像缩放到与UITextView相同的宽度。这是我加载字符串的方式:

if let text = try? NSMutableAttributedString(URL: NSBundle.mainBundle().URLForResource("License agreement", withExtension: "rtfd")!, options: [NSDocumentTypeDocumentAttribute : NSRTFDTextDocumentType], documentAttributes: nil) {

        textView.attributedText = text
    }

我也尝试使用带有img style="width: 100%"的webarchive文件,但这也没有起作用。
有什么最好的方法可以以这样的方式显示rtfd或其他文档,使得图像按比例缩放以适应宽度?

遍历 NSAttributedString 寻找带属性的 NSAttachmentAttributeName。然后,您可以根据 UITextView 的宽度调整图像大小。 - Larme
2个回答

3

感谢Larme的评论,我成功地按照以下方式实现了它:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    prepareTextImages()
}

private var text: NSMutableAttributedString?
private func prepareTextImages() {
    let width  = CGRectGetWidth(self.view.frame) - self.containerView.frame.origin.x * 2 - 10
    text?.enumerateAttribute(NSAttachmentAttributeName, inRange: NSRange(location: 0, length: text!.length), options: [], usingBlock: { [width] (object, range, pointer) in
        let textViewAsAny: Any = self.textView
        if let attachment = object as? NSTextAttachment, let img = attachment.imageForBounds(self.textView.bounds, textContainer: textViewAsAny as? NSTextContainer, characterIndex: range.location) {
            if attachment.fileType == "public.png" {
                let aspect = img.size.width / img.size.height
                if img.size.width <= width {
                    attachment.bounds = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
                    return
                }
                let height = width / aspect
                attachment.bounds = CGRect(x: 0, y: 0, width: width, height: height)
            }
        }
        })
}

这里有一个小问题 - 在滚动时,我会看到查看该图像时的小延迟。在不改变大小的情况下,完整大小的图像不会出现这种情况。有人能想到原因吗?


为什么你要在 viewDidLayoutSubviews() 中重新设置属性文本? - Larme
你说得对,我后来删除了这个。忘记在这里更改了。 - Damian Dudycz
attachment.imageForBounds() now appears to be attachment.image(forBounds: self.textView.bounds, textContainer: textViewAsAny as? NSTextContainer, characterIndex: range.location) - Stewart Macdonald

0
如果您使用attributeText属性对textView进行po操作,您会发现它有许多类似这样的对象:
NSAttachment = "<NSTextAttachment: 0x6000002a39c0> \"XXXXXXX.jpg\"";
NSColor = "kCGColorSpaceModelRGB 0 0 0 1 ";
NSFont = "<UICTFont: 0x7f8356400f60> font-family: \"Times New Roman\"; font-weight: normal; font-style: normal; font-size: 12.00pt";
NSKern = 0;
NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 12, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 15/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n), DefaultTabInterval 36, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";
NSStrokeColor = "kCGColorSpaceModelRGB 0 0 0 1 ";
NSStrokeWidth = 0;  

然后你会发现NSTextAttachment就是Bingo。所以枚举这些对象,获取NSTextAttachment并更改其边界: (我将图像设置为距离屏幕右侧有10像素的边距)

[attributeString enumerateAttribute:NSAttachmentAttributeName inRange:NSMakeRange(0, attributeString.length) options:0 usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {

            if (value) {

                if ([value isKindOfClass:[NSTextAttachment class]]) {

                    NSTextAttachment *attach = value;
                    CGFloat scale  = SCREEN_WIDTH / attach.bounds.size.width;
                    CGRect newRect = CGRectMake(attach.bounds.origin.x, attach.bounds.origin.y,SCREEN_WIDTH-10, attach.bounds.size.height*scale);
                    attach.bounds  = newRect;
                }
            }
        }];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接