UILabel 或 UITextView 加載有網(wǎng)絡(luò)圖片的 html String

加載 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)成的代碼利用。只能跟著只言片語組合。一天的琢磨,終于解決。

思路:

  1. 抽出 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)化)。
  2. 利用 rangeshtml 中的 img標(biāo)簽 剔除并分割,并將剩余的內(nèi)容添加到數(shù)組 substrings 中。
  3. 利用 substringsimageURLs 組成新的 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)分享能夠幫到您。如果有其他更好的方法,歡迎積極探討。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容