两种方法实现UILabel图文并茂的显示html文本

本文讲述用2中方法在UILabel中显示带图片和文字的HTML文本。
先预览下显示效果:
显示效果
如果你的设备时iOS 9或以上,默认只允许HTTPS,请打开HTTP请求许可,参照:iOS 9打开HTTP请求许可

第一种方案:

//HTML文本 包含图片、文本
NSString *htmlString=@"< img src=http://upload-images.jianshu.io/upload_images/937405-50a8ad2d8866fc12.png>  花羊羊领取了你的红包"
UILabel \*label=[UILabel alloc] initWithFrame:CGRectMake(50, 200, 220, 20)];
[self.view addSubview:label];
UIFont \*font=[UIFont systemFontOfSize:14];
label.font=font;
NSDictionary \\*optoins=@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,
                            NSFontAttributeName:font};
NSData \*data=[htmlString dataUsingEncoding:NSUnicodeStringEncoding];
NSAttributedString \*attributeString=[[NSAttributedString alloc] initWithData:data
                                                                     options:optoins
                                                          documentAttributes:nil
                                                                       error:nil];
label.attributedText=attributeString;
方案一点评: 这种方案只是实现了显示,显示效果好不好是另一回事。事实证明,这种方案的显示效果很不好: ![方案一显示效果](http://upload-images.jianshu.io/upload_images/937405-d810311964b43dab.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 我们现在要对方案一进行优化。 方案一优化思路:1.缩小图片,让图片与字体显示差不多大; 2.让字体显示垂直方向居中。 优化后的方案一:
//HTML文本 包含图片、文本
NSString *htmlString=@"< img src=http://upload-images.jianshu.io/upload_images/937405-50a8ad2d8866fc12.png>  花羊羊领取了你的红包"
//我们可以先把src对应的图片解析出来,放到本地
NSRange httpRange=[htmlString rangeOfString:@"http://"];
NSRange endRange=[htmlString rangeOfString:@".png"];
NSString \*picString=[htmlString substringWithRange:NSMakeRange(httpRange.location, endRange.location+endRange.length-httpRange.location)];
[[SDWebImageDownloader sharedDownloader] downloadImageWithURL:[NSURL URLWithString:picString] options:nil progress:nil completed:^(UIImage \\*image, NSData \\*data, NSError \*error, BOOL finished) {
    //按照字体大小缩小图片,具体实现在下文
     UIImage \\*scaledImage=[self scaleImage:image font:font];
     NSData \*imgData=UIImagePNGRepresentation(scaledImage);
     NSString \\*libPath=[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,     NSUserDomainMask, YES) lastObject];
    NSString \\*cachePath=[libPath stringByAppendingPathComponent:@"Caches"];
    NSString \\*scaledImagesPath=[cachePath stringByAppendingPathComponent:@"scaledImages"];
    if(![[NSFileManager defaultManager] fileExistsAtPath:scaledImagesPath]){
        [[NSFileManager defaultManager] createDirectoryAtPath:scaledImagesPath withIntermediateDirectories:YES attributes:nil error:nil];
    }
NSString\\ *picName=[[picString componentsSeparatedByString:@"/"] lastObject];
    NSString \\*filePath=[scaledImagesPath stringByAppendingPathComponent:picName];
    [imgData writeToFile:filePath atomically:YES];
    NSString \\*path=[NSURL fileURLWithPath:filePath].absoluteString;
//用本地的图片路径替换远程图片路径
htmlString=[htmlString stringByReplacingOccurrencesOfString:picString withString:path];
}];
UILabel \\*label=[UILabel alloc] initWithFrame:CGRectMake(50, 200, 220, 20)];
[self.view addSubview:label];
UIFont \\*font=[UIFont systemFontOfSize:14];
label.font=font;
NSDictionary \\*optoins=@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,
                            NSFontAttributeName:font};
NSData \\*data=[htmlString dataUsingEncoding:NSUnicodeStringEncoding];
NSAttributedString \\*attributeString=[[NSAttributedString alloc] initWithData:data
                                                                     options:optoins
                                                          documentAttributes:nil
                                                                       error:nil];
label.attributedText=attributeString;

优化后的方案一显示效果

优化后的方案一显示效果差强人意。这种方法成功的解决了图片大小的问题,以及文本不居中的问题,但图片没有居中对齐,网上也找不到方法,只有继续探寻。

方案二:

//HTML文本 包含图片、文本
NSString *htmlString=@"< img src=http://upload-images.jianshu.io/upload_images/937405-50a8ad2d8866fc12.png>  花羊羊领取了你的红包"
//我们可以先把src对应的图片解析出来,放到本地
NSRange httpRange=[htmlString rangeOfString:@"http://"];
NSRange endRange=[htmlString rangeOfString:@".png"];
NSString \*picString=[htmlString substringWithRange:NSMakeRange(httpRange.location, endRange.location+endRange.length-httpRange.location)];
UIImage \*scaledImage;
[[SDWebImageDownloader sharedDownloader] downloadImageWithURL:[NSURL URLWithString:picString] options:nil progress:nil completed:^(UIImage \*image, NSData \*data, NSError \*error, BOOL finished) {
    //按照字体大小缩小图片,具体实现在下文
     scaledImage=[self scaleImage:image font:font];
     NSData \*imgData=UIImagePNGRepresentation(scaledImage);
     NSString \*libPath=[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,     NSUserDomainMask, YES) lastObject];
    NSString \*cachePath=[libPath stringByAppendingPathComponent:@"Caches"];
    NSString \*scaledImagesPath=[cachePath stringByAppendingPathComponent:@"scaledImages"];
    if(![[NSFileManager defaultManager] fileExistsAtPath:scaledImagesPath]){
        [[NSFileManager defaultManager] createDirectoryAtPath:scaledImagesPath withIntermediateDirectories:YES attributes:nil error:nil];
    }
NSString \\*picName=[[picString componentsSeparatedByString:@"/"] lastObject];
    NSString \\*filePath=[scaledImagesPath stringByAppendingPathComponent:picName];
    [imgData writeToFile:filePath atomically:YES];
//用空字符串替换远程图片路径
htmlString=[htmlString stringByReplacingOccurrencesOfString:picString withString:@""];
}];


UILabel \*label=[UILabel alloc] initWithFrame:CGRectMake(50, 200, 220, 20)];
[self.view addSubview:label];
UIFont \*font=[UIFont systemFontOfSize:14];
label.font=font;
//利用NSTextAttachment文UILabel添加图片,并调整位置实现居中对齐
NSTextAttachment *attach=[[NSTextAttachment alloc] init];
attach.bounds=CGRectMake(2, -(label.frame.size.height-font.pointSize)/2, 12, 14);
attach.image=scaledImage;
NSMutableAttributedString \*componets=[[NSMutableAttributedString alloc] init];
NSAttributedString \*imagePart=[NSAttributedString attributedStringWithAttachment:attach];
[componets appendAttributedString:imagePart];
NSDictionary \*optoins=@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,
                            NSFontAttributeName:font};
NSData \*data=[htmlString dataUsingEncoding:NSUnicodeStringEncoding];
NSAttributedString \*textPart=[[NSAttributedString alloc] initWithData:data
                                                                     options:optoins
                                                          documentAttributes:nil
                                                                       error:nil];
[componets appendAttributedString:textPart];
label.attributedText=componets;

方案二的显示效果
点评:
方案二显示效果略复杂,但是达到了我们需要的正常显示效果。

最后,附上根据字体大小缩小图片的方法:

-(UIImage \*)scaleImage:(UIImage \*)origin font:(UIFont \*)font{

    CGFloat imgH=origin.size.height;
    CGFloat imgW=origin.size.width;
    CGFloat width;
    CGFloat height;
    CGFloat fontHeight=font.pointSize;
    if(imgW>imgH){

        width=fontHeight;
        height=fontHeight/imgW\*imgH;
    }
    else{
        height=fontHeight;
        width=fontHeight/imgH\*imgW;
    }
    UIGraphicsBeginImageContext(CGSizeMake(width, height));
    [origin drawInRect:CGRectMake(0, 0, width, height)];
    UIImage \*scaledImage=UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return scaledImage;
}