在带有属性文本的UITextView中重绘NSTextAttachments

我有一个覆盖NSTextAttachment子类
attachmentBoundsForTextContainer:proposedLineFragment:glyphPosition:characterIndex:
imageForBounds:textContainer:characterIndex:

我需要在某个时候重新绘制附件。 在UITextView上调用setNeedsDisplay不起作用。

有任何想法吗? 我想避免重新创build附件和/或属性string。

你会想使用textView.layoutManager的方法之一。

  • invalidateDisplayCharacterRange:
    • imageForBounds:textContainer:characterIndex:将被再次调用。
    • attachmentBoundsForTextContainer:[...]Index:不会被调用。
    • 如果image已经被另外一个相同的大小改变,那就好了。
  • invalidateLayoutForCharacterRange:actualCharacterRange:
    • imageForBounds:textContainer:characterIndex:将被再次调用。
    • attachmentBoundsForTextContainer:[...]Index:将被再次调用。
    • 好,如果image已被另一个不同的大小更改。

如果你只是想更新一个附件,你可能会发现我写这个帮助者的方法是有帮助的:

 - (NSRange)rangeOfAttachment:(NSTextAttachment *)attachment { __block NSRange ret; [self.textStorage enumerateAttribute:NSAttachmentAttributeName inRange:NSMakeRange(0, self.textStorage.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) { if (attachment == value) { ret = range; *stop = YES; } }]; return ret; } 

您可以将此方法的结果NSRange传递给这些invalidate方法的第一个参数。 对于第二个方法的actualCharacterRange:参数,我一直传递NULL没有任何问题。

那么,经过一些挖掘,可以通过使布局pipe理器无效:

 [textView.layoutManager invalidate....] 

苹果文档

如果你只是想改变一个图像初始化的NSTextAttachment,我build议你使用

 setAttachmentSize:size forGlyphRange:range