加載 html string很簡(jiǎn)單,就是UILabel 或 UITextView attributedText屬性。
其中的 attributedText用以下方式來創(chuàng)建:
NSAttributedString *tmpString = [[NSMutableAttributedString alloc] initWithData:[htmlText dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType} documentAttributes:nil error:nil];
當(dāng)然也可以用 UIWebView 。
然而問題來了,html string 中包含網(wǎng)絡(luò)資源圖片用無法加載。文字內(nèi)容能很好的展示,圖片的位置也空出來了,但就是無法顯示。
這是一個(gè)沒法回避的問題。網(wǎng)上搜遍,沒有現(xiàn)成的代碼利用。只能跟著只言片語組合。一天的琢磨,終于解決。
思路:
- 抽出
html中的img標(biāo)簽對(duì)應(yīng)的url保存到數(shù)組imageURLs中, 同時(shí)記住img標(biāo)簽的range(NSRange轉(zhuǎn) NSString)添加到ranges中 (這個(gè)網(wǎng)上有現(xiàn)成的方法,我也進(jìn)行了借鑒和優(yōu)化)。 - 利用
ranges將html中的img標(biāo)簽剔除并分割,并將剩余的內(nèi)容添加到數(shù)組substrings中。 - 利用
substrings和imageURLs組成新的NSAttributedString。
效果如下:( 帖子詳情 中,最上面的圖片是個(gè) imageview,其他所有內(nèi)容包括圖片為一個(gè) label 展示的)

image
示例
self.contentLabel.attributedText = [HTMLHelper attributedTextFromHTML:html];
具體代碼:
HTMLHelper.h
#import <Foundation/Foundation.h>
@interface HTMLHelper : NSObject
/**
解析原始的 html string 為 NSAttributedString
@param originHtml html標(biāo)簽 string
@return NSAttributedString
*/
+ (NSAttributedString *)attributedTextFromHTML:(NSString *)originHtml;
@end
HTMLHelper.m
#import "HTMLHelper.h"
@interface HTMLHelper ()
@end
@implementation HTMLHelper
//獲取webView中的所有圖片URL
- (NSArray *)getImageurlFromHtml:(NSMutableAttributedString *) webString {
NSMutableArray *imageurlArray = [[NSMutableArray alloc] init];
NSMutableArray *ranges = [[NSMutableArray alloc] init];
if (webString.length==0) {
return nil;
}
NSString *webStr = [webString.string copy];
//標(biāo)簽匹配
NSString *parten = @"<img(.*?)>";
NSError* error = NULL;
NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:parten options:0 error:&error];
NSArray* match = [reg matchesInString:webStr options:0 range:NSMakeRange(0, [webString length] - 1)];
for (NSTextCheckingResult * result in match) {
//過去數(shù)組中的標(biāo)簽
NSRange range = [result range];
NSString *rangeString = NSStringFromRange(range);
NSLog(@"-------add item:%@", rangeString);
[ranges addObject:rangeString];
NSString * subString = [webStr substringWithRange:range];
//從圖片中的標(biāo)簽中提取ImageURL
NSRegularExpression *subReg = [NSRegularExpression regularExpressionWithPattern:@"http://(.*?)\"" options:0 error:NULL];
NSArray* match = [subReg matchesInString:subString options:0 range:NSMakeRange(0, [subString length] - 1)];
NSRegularExpression *subRegOne = [NSRegularExpression regularExpressionWithPattern:@"https://(.*?)\"" options:0 error:NULL];
NSArray *matchOne = [subRegOne matchesInString:subString options:0 range:NSMakeRange(0, [subString length] - 1)];
NSMutableArray *tmpItems = [[NSMutableArray alloc] init];
if (match.count > 0) {
[tmpItems addObjectsFromArray:match];
}
if (matchOne.count > 0) {
[tmpItems addObjectsFromArray:matchOne];
}
if (tmpItems.count > 0) {
NSTextCheckingResult * subRes = tmpItems[0];
NSRange subRange = [subRes range];
subRange.length = subRange.length -1;
NSString * imagekUrl = [subString substringWithRange:subRange];
//將提取出的圖片URL添加到圖片數(shù)組中
[imageurlArray addObject:imagekUrl];
}
}
return imageurlArray;
}
+ (NSAttributedString *)attributedTextFromHTML:(NSString *)html {
if (html.length == 0 ) {
return [[NSAttributedString alloc] init];
}
NSMutableString *mutableHtml = [html mutableCopy];
NSMutableArray<NSString *> *subStrings = [[NSMutableArray alloc] init];
NSMutableArray<NSString *> *imageurlArray = [[NSMutableArray alloc] init];
NSMutableArray<NSString *> *ranges = [[NSMutableArray alloc] init];
//標(biāo)簽匹配
NSString *parten = @"<img(.*?)>";
NSError* error = NULL;
NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:parten options:0 error:&error];
NSArray* match = [reg matchesInString:html options:0 range:NSMakeRange(0, [html length] - 1)];
if (match.count > 0) {
for (NSTextCheckingResult *result in match) {
//過去數(shù)組中的標(biāo)簽
NSRange range = [result range];
NSString *rangeString = NSStringFromRange(range);
NSLog(@"-------add item:%@", rangeString);
[ranges addObject:rangeString];
NSString * subString = [html substringWithRange:range];
//從圖片中的標(biāo)簽中提取ImageURL
NSRegularExpression *subReg = [NSRegularExpression regularExpressionWithPattern:@"http://(.*?)\"" options:0 error:NULL];
NSArray* match = [subReg matchesInString:subString options:0 range:NSMakeRange(0, [subString length] - 1)];
NSRegularExpression *subRegOne = [NSRegularExpression regularExpressionWithPattern:@"https://(.*?)\"" options:0 error:NULL];
NSArray *matchOne = [subRegOne matchesInString:subString options:0 range:NSMakeRange(0, [subString length] - 1)];
NSMutableArray *tmpItems = [[NSMutableArray alloc] init];
if (match.count > 0) {
[tmpItems addObjectsFromArray:match];
}
if (matchOne.count > 0) {
[tmpItems addObjectsFromArray:matchOne];
}
if (tmpItems.count > 0) {
NSTextCheckingResult * subRes = tmpItems[0];
NSRange subRange = [subRes range];
subRange.length = subRange.length -1;
NSString * imagekUrl = [subString substringWithRange:subRange];
//將提取出的圖片URL添加到圖片數(shù)組中
[imageurlArray addObject:imagekUrl];
}
}
}
///將 html 按圖片分割,并加入數(shù)組
NSLog(@"ranges:%@", ranges.description);
NSLog(@"imgURLs:%@", imageurlArray.description);
if (ranges.count > 0) {
NSUInteger startIndex = html.length;
NSUInteger length = 0;
for ( int index = ranges.count - 1; index >= 0; index--) {
NSLog(@"currentRange:%@", ranges[index]);
NSLog(@"mutableHtml length:%ld", mutableHtml.length);
NSRange tmpRange = NSRangeFromString(ranges[index]);
startIndex = tmpRange.location + tmpRange.length;
length = mutableHtml.length - startIndex;
NSLog(@"start index:%ld", startIndex);
if (startIndex < mutableHtml.length ) {
NSRange subStringRange = NSMakeRange(startIndex, length);
NSString *tmpString = [mutableHtml substringWithRange:subStringRange];
if (subStrings.count == 0) {
[subStrings addObject:tmpString];
} else {
[subStrings insertObject:tmpString atIndex:0];
}
}
mutableHtml = [[mutableHtml substringToIndex:tmpRange.location] mutableCopy];
}
if (mutableHtml.length > 0) {
if (subStrings.count == 0) {
[subStrings addObject:mutableHtml];
} else {
[subStrings insertObject:mutableHtml atIndex:0];
}
}
}
NSMutableAttributedString *terminalString = [HTMLHelper attributedTextFrom:subStrings imgSrcs:imageurlArray];
return [terminalString copy];
}
/**
將數(shù)組中的字符串和圖片資源重組為 AttributedString
@param subStrings <#subStrings description#>
@param imgURLs <#imgURLs description#>
@return <#return value description#>
*/
+ (NSMutableAttributedString *)attributedTextFrom:(NSArray *)subStrings imgSrcs:(NSArray *)imgURLs {
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] init];
if (subStrings.count > 0) {
for (int index = 0; index < subStrings.count; index++) {
NSAttributedString *tmpString = [[NSMutableAttributedString alloc] initWithData:[subStrings[index] dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType} documentAttributes:nil error:nil];
[string appendAttributedString:tmpString];
if (imgURLs.count > index) {
NSTextAttachment *attach = [[NSTextAttachment alloc] init];
NSString *imageUrlStr = imgURLs[index];
NSURL *url = [NSURL URLWithString:imageUrlStr];
NSData *imageData = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:imageData];
attach.image = image;
CGSize size = CGSizeMake(kScreen_Width - 10, image.size.height / image.size.width * kScreen_Width);
attach.bounds = CGRectMake(0, 0, size.width, size.height);
NSAttributedString *attachString = [NSAttributedString attributedStringWithAttachment:attach];
// 點(diǎn)擊圖片跳轉(zhuǎn)到safari
NSMutableAttributedString *maImageStr = [[NSMutableAttributedString alloc] initWithAttributedString:attachString];
[maImageStr addAttribute:NSLinkAttributeName value:url.absoluteString range:NSMakeRange(0, maImageStr.length)];
[string appendAttributedString:maImageStr];
}
}
}
return string;
}
@end
最后,希望這點(diǎn)分享能夠幫到您。如果有其他更好的方法,歡迎積極探討。