圖文混排實現(xiàn)
最近公司的項目需要用到圖文混排編輯來書寫個人簡介溯革,由于需求功能比較簡單姓赤,所以找到了SimpleWord崭篡,個人感覺功能還是很強大的谷扣,但在實現(xiàn)需求過程中發(fā)現(xiàn)了一些問題涤躲,特此記錄一下县遣。
踩坑
1、在web上正常加載的圖片(圖1)袍睡,通過富文本的下面的方式顯示在textView上會出現(xiàn)圖片寬高不適配的情況知染,如圖2所示;
textView.attributedText = [[NSAttributedString alloc] initWithData:[autoStr dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
2斑胜、由于圖片都是網(wǎng)絡圖片控淡,顯示在textView上如果不對圖片進行修改,點擊保存止潘,用SimpleWord寫好的的方法將原生的 AttributedString 導出成 HTML的方式掺炭,會存在<img src="null"/>的問題。
填坑
1凭戴、針對第一個問題涧狮,我將得到的html加上img的css樣式,代碼如下,完美解決圖片不適配的問題者冤!
NSString *autoStr = [NSString stringWithFormat:@"<head><style>img{width:%f !important;height:auto}</style></head>%@",SCREENW - 2*20,_htmlString];
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithData:[autoStr dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
2肤视、針對第二個問題,圖片標簽src="null"的問題涉枫,這個問題還是困惑了很久的邢滑,后來通過查看他將原生的 AttributedString 導出成 HTML的方法,由于代碼較長愿汰,就貼出導出img的方法困后;
? ? 可以分析得出導出img的思路是獲取attributes中的NSAttachment類,在拿到NSAttachment的userInfo屬性衬廷,但這個userInfo是NSAttachment的分類屬性摇予,我們轉(zhuǎn)成attributedString時候并沒有給他賦初值,所以直接對原來圖片進行保存的話吗跋,肯定是沒有值的侧戴!
NSDictionary *attributes = [attributedString attributesAtIndex:effectiveRange.location effectiveRange:&effectiveRange];
NSTextAttachment *attachment = attributes[@"NSAttachment"];
NSParagraphStyle *paragraph = attributes[@"NSParagraphStyle"];
LMParagraphConfig *paragraphConfig = [[LMParagraphConfig alloc] initWithParagraphStyle:paragraph type:LMParagraphTypeNone];
if (attachment) {
switch (attachment.attachmentType) {
case LMTextAttachmentTypeImage: // attachment.fileWrapper.preferredFilename
[htmlContent appendString:[NSString stringWithFormat:@"<img src=\"%@\" width=\"100%%\"/>", attachment.userInfo]];
break;
default:
break;
}
}
找到問題之后,接下來就是解決了小腊,現(xiàn)在要做的就是在原來attributedString的基礎上取出NSTextAttachment救鲤,并給其userInfo屬性賦上我們的圖片地址;參照圖片生成NSTextAttachment 的方法
- (NSTextAttachment *)insertImage:(UIImage *)image秩冈;
我們在得出修改后的富文本字符串之前本缠,我們要先拿到所有的img標簽,在這里我用的是Hpple入问。
+ (NSArray *)getSrcArrWithHtmlString:(NSString *)htmlString {
NSData *data =[htmlString dataUsingEncoding:NSUnicodeStringEncoding];
NSString *result = [[NSString alloc] initWithData:data? encoding:NSUTF8StringEncoding];? //data轉(zhuǎn)字符串 為了打印不是亂碼
SLog(@"------%@",result);
TFHpple *Hpple = [[TFHpple alloc]initWithHTMLData:data];
NSArray *array =[Hpple searchWithXPathQuery:@"http://img"]; //獲取到為img標簽數(shù)組
NSMutableArray *secArr = [NSMutableArray array];
for (TFHppleElement *HppleElement in array) {
NSDictionary *node = HppleElement.attributes;
[secArr addObject:node[@"src"]];
}
return secArr;
}
最后丹锹,我們可以得出修改后的富文本字符串,大致代碼如下芬失;
// 改變attachment.userInfo
+ (NSAttributedString *)attStringFromAttributedString:(NSAttributedString *)attributedString textView:(UITextView *)textView htmlString:(NSString *)htmlString {
NSMutableAttributedString *copyAttr = [[NSMutableAttributedString alloc] initWithAttributedString:attributedString];
NSRange effectiveRange = NSMakeRange(0, 0);
int section = 0;
NSArray *secArr = [self getSrcArrWithHtmlString:htmlString];
while (effectiveRange.location + effectiveRange.length < attributedString.length) {
NSDictionary *attributes = [attributedString attributesAtIndex:effectiveRange.location effectiveRange:&effectiveRange];
NSTextAttachment *attachment = attributes[@"NSAttachment"];
if (attachment) {
attachment.attachmentType = LMTextAttachmentTypeImage;
attachment.userInfo = secArr[section]; // 獲取網(wǎng)絡圖片路徑
section++;
//
NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment];
NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:@"\n"];
[attributedStr insertAttributedString:attachmentString atIndex:0];
[attributedStr addAttributes:textView.typingAttributes range:NSMakeRange(0, attributedStr.length)];
// 添加樣式
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setParagraphStyle:[NSParagraphStyle defaultParagraphStyle]];
paragraphStyle.paragraphSpacingBefore = 8.f;
paragraphStyle.paragraphSpacing = 8.f;
[attributedStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, attributedStr.length)];
[copyAttr replaceCharactersInRange:effectiveRange withAttributedString:attributedStr];
}
effectiveRange = NSMakeRange(effectiveRange.location + effectiveRange.length, 0);
}
return copyAttr;
}
PS:由于我這次項目只是簡單的圖文編輯跟混排楣黍,需要的內(nèi)容不是很多,所以采用NSAttributedString進行展示棱烂,如果需要大量的圖片及文字展示租漂,例如閱讀類的APP,建議還是用coreText或textKit進行排版颊糜!