美文网首页程序员iOS开发攻城狮的集散地收藏ios
iOS富文本手动刷新和异步替换网络图片

iOS富文本手动刷新和异步替换网络图片

作者: 宋唐不送糖 | 来源:发表于2018-08-01 11:26 被阅读0次
    引言:由于贫道比较懒而且大神太多,这段时间没有啥干货可拿得出手。近日闲暇之余,在时隔2年之后重回简书装X。近期在学习OC底层原理,之后会写一些底层的文章供广大道友借鉴。

    移动端iOS开发中,少不了遇到NSAttributedString(富文本字典集合)富文本形式进行图文混排。如果想替换富文本内部某个位置的图片,有一种方式是找到range,然后重新生成此段range的富文本,然后将总文本进行局部替换。此方式贫道觉得有些许难以确定具体替换的位置。还有一种方式是,可以通过遍历来获取内部各个段落文本字典。具体方法名是:
    enumerateAttributesInRange: options:NSAttributedStringEnumerationReverse usingBlock:

    block我们知道,回调是异步执行的。加载网络图片也是异步执行的,这就导致问题
    1、图片显示出来了,但是还是旧图片。
    2、预先不知道图片的大小,但是NSTextAttachment是需要设定大小的,所以一开始就用的placeholder图片的大小,等图片下载完成候再更新NSTextAttachment的bounds,发现无效。
    例子:

    [[SDWebImageManager sharedManager] loadImageWithURL:[NSURL URLWithString:url] options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) 
    {} completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL)
    {
            UIImage *linkImage = image;
            attachment.image = videoImage;
    }];
    

    但是你如果重新退出这个ViewController再进入的话,图片神奇般的重新显示了。所以十有八九是TextView没有刷新的缘故了。如果调用textView的setNeedsLayout是没有用的,这个方法的用途是用来刷新subView的,对于TextView中的内容布局是没有影响的。


    重点:

    我们要用到的是CoreText中的NSLayoutManager,先看一下我们要用到的方法:
    [self.textView.layoutManager invalidateLayoutForCharacterRange:range actualCharacterRange:NULL];

    苹果文档解释是(已翻译):

    定义 Invalidates the layout information for the glyphs mapped to the given range of characters.这个方法会调用下面的方法:
    1、imageForBounds:textContainer:characterIndex: will be called again.
    2、attachmentBoundsForTextContainer:[…]Index: will be called again.

    所以,我们只要在NSTextAttachment.image赋值或者bouds改变之后,调用该方法就可以刷新textView的布局,让图片大小正常显示出来了。


    参考:
    stackoverflow

    相关文章

      网友评论

        本文标题:iOS富文本手动刷新和异步替换网络图片

        本文链接:https://www.haomeiwen.com/subject/jvjlvftx.html