Redrawing NSTextAttachments in an UITextView with attributed text

落花浮王杯 提交于 2019-11-29 14:37:28

问题


I have a NSTextAttachment subclass with overridden
attachmentBoundsForTextContainer:proposedLineFragment:glyphPosition:characterIndex:
imageForBounds:textContainer:characterIndex:.

I need to redraw the attachment(s) at some point. Calling setNeedsDisplay on the UITextView doesn't work.

Any ideas? I'd like to avoid recreating attachments and/or the attributed string.


回答1:


You'll want to use one of textView.layoutManager's methods.

  • invalidateDisplayCharacterRange:
    • imageForBounds:textContainer:characterIndex: will be called again.
    • attachmentBoundsForTextContainer:[...]Index: will not be called again.
    • Good if the image has been changed with another one of the same size.
  • invalidateLayoutForCharacterRange:actualCharacterRange:
    • imageForBounds:textContainer:characterIndex: will be called again.
    • attachmentBoundsForTextContainer:[...]Index: will be called again.
    • Good if the image has been changed with another one of a different size.

If you just want to update a single attachment, you may find this helper method I wrote helpful:

- (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;
}

You can pass the resulting NSRange of this method to the first argument of either of those invalidate methods. For the actualCharacterRange: argument of the second method, I've been passing in NULL without any problems.




回答2:


Well, after some digging, that can done by invalidating the layout manager:

[textView.layoutManager invalidate....]

Apple docs




回答3:


If you just want to change the NSTextAttachment which is init by a image, I suggest you to use

setAttachmentSize:size forGlyphRange:range


来源:https://stackoverflow.com/questions/24509660/redrawing-nstextattachments-in-an-uitextview-with-attributed-text

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!