1. 程式人生 > >iOS富文字手動重新整理和非同步替換網路圖片

iOS富文字手動重新整理和非同步替換網路圖片

CSDN註冊好幾年一直沒用過於是乎今天心血來潮寫一篇技術交流貼,以供有需要的道友。

移動端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的佈局,讓圖片大小正常顯示出來了。