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