【问题标题】:Redrawing NSTextAttachments in an UITextView with attributed text使用属性文本在 UITextView 中重绘 NSTextAttachments
【发布时间】:2014-08-21 23:27:54
【问题描述】:
我有一个被重写的 NSTextAttachment 子类
attachmentBoundsForTextContainer:proposedLineFragment:glyphPosition:characterIndex:
imageForBounds:textContainer:characterIndex:。
我需要在某个时候重新绘制附件。在 UITextView 上调用 setNeedsDisplay 不起作用。
有什么想法吗?我想避免重新创建附件和/或属性字符串。
【问题讨论】:
标签:
ios
uitextview
nstextattachment
【解决方案1】:
您需要使用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,没有任何问题。
【解决方案2】:
好吧,经过一番挖掘,可以通过使布局管理器无效来完成:
[textView.layoutManager invalidate....]
Apple docs
【解决方案3】:
如果你只是想改变图片初始化的NSTextAttachment,我建议你使用
setAttachmentSize:size forGlyphRange:range