本文讲述用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; }