Migrating NSTextAttachments to UITextView with text attribute

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

I need to redraw attachments at some point. Calling setNeedsDisplay in a UITextView does not work.

Any ideas? I would like to avoid recreating the attachments and / or attribute string.

+7
ios uitextview nstextattachment
source share
3 answers

You want to use one of the textView.layoutManager methods.

  • invalidateDisplayCharacterRange:
    • imageForBounds:textContainer:characterIndex: will be called again.
    • attachmentBoundsForTextContainer:[...]Index: will not be called.
    • Well, if image was changed by another with the same .
  • invalidateLayoutForCharacterRange:actualCharacterRange:
    • imageForBounds:textContainer:characterIndex: will be called again.
    • attachmentBoundsForTextContainer:[...]Index: will be called again.
    • Well, if the image was resized with a different size .

If you just want to update one attachment, you can find this helper method, which I wrote useful:

 - (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 received NSRange this method to the first argument of any of these invalidate methods. For the argument actualCharacterRange: second method, I pass into NULL without any problems.

+16
source share

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

 [textView.layoutManager invalidate....] 

Apple docs

+2
source share

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

 setAttachmentSize:size forGlyphRange:range 
-one
source share

All Articles