9

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

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

有任何想法吗?我想避免重新创建附件和/或属性字符串。

4

3 回答 3

18

你会想要使用textView.layoutManager's 方法之一。

  • 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没有任何问题地传入。

于 2014-07-26T17:06:54.880 回答
3

好吧,经过一番挖掘,可以通过使布局管理器无效来完成:

[textView.layoutManager invalidate....]

苹果文档

于 2014-07-01T16:05:52.313 回答
-1

如果您只想更改由图像初始化的 NSTextAttachment,我建议您使用

setAttachmentSize:size forGlyphRange:range
于 2016-07-13T13:57:36.160 回答