//
// HTMLAnalysisHelper.m
// HTMLAnalysisDemo
//
// Created by ztcj_develop_mini on 2019/3/25.
// Copyright © 2019 ztcj_develop_mini. All rights reserved.
//
#import "HTMLAnalysisHelper.h"
#import "AttributedStrModel.h"
#import "YYText.h"
#import
#import
@interface HTMLAnalysisHelper ()
@property (nonatomic, strong)NSMutableArray *attributeStrArr;
@property (nonatomic, strong)NSMutableArray *imgUrlStrArr; //html中所嵌的图片url 数组
@end
@implementation HTMLAnalysisHelper
- (instancetype)init
{
if (self = [super init]) {
self.fontSize = kDefaultFontSize;
self.imageWidth = kDefaultImgWidth;
self.textLineSpacing = kDefaultTextLineSpacing;
self.paragraphSpacing = kDefaultParagraphSpacing;
}
return self;
}
- (void)setFontSize:(CGFloat)fontSize
{
_fontSize = fontSize;
[self getAttributeStrWithOpenState:YES];
[self getAttributeStrWithOpenState:NO];
}
- (void)setImageWidth:(CGFloat)imageWidth
{
_imageWidth = imageWidth;
[self getAttributeStrWithOpenState:YES];
[self getAttributeStrWithOpenState:NO];
}
- (void)setTextLineSpacing:(CGFloat)textLineSpacing
{
_textLineSpacing = textLineSpacing;
[self getAttributeStrWithOpenState:YES];
[self getAttributeStrWithOpenState:NO];
}
- (void)setParagraphSpacing:(CGFloat)paragraphSpacing
{
_paragraphSpacing = paragraphSpacing;
[self getAttributeStrWithOpenState:YES];
[self getAttributeStrWithOpenState:NO];
}
#pragma mark -- 解析字符串,放到一个数组里
- (void)analysisWithHTMLStr:(NSString *)htmlStr{
dispatch_async(dispatch_get_main_queue(), ^{
[self.attributeStrArr removeAllObjects];
//先转成富文本
NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc]initWithData:[htmlStr dataUsingEncoding:NSUnicodeStringEncoding] options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType} documentAttributes:nil error:nil];
//枚举取出所有富文本,放到一个AttributedStrModel数组里
__weak typeof(self) wself = self;
[attributeString enumerateAttributesInRange:NSMakeRange(0, attributeString.length) options:0 usingBlock:^(NSDictionary * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
// NSLog(@"%@",attrs);
//创建模型装载数据对象
AttributedStrModel *attributeStrModel = [[AttributedStrModel alloc]init];
NSTextAttachment *attachment = [attrs objectForKey:NSAttachmentAttributeName];
if (attachment) { //图片
attributeStrModel.type = ImageAttributedStrType;
// attachment.fileWrapper.preferredFilename 拿到的是URL路径最后面的图片名称
attributeStrModel.imgName = [attachment.fileWrapper.preferredFilename componentsSeparatedByString:@"."].firstObject;
}
else{ // 文本
attributeStrModel.type = TextAttributedStrType;
//调整字体大小为我们想要的大小
attributeStrModel.attributeStr = [[NSMutableAttributedString alloc]initWithAttributedString:[attributeString attributedSubstringFromRange:range]];
UIFont *font = [attrs objectForKey:NSFontAttributeName];
if (!font) {
font = [UIFont systemFontOfSize:self.fontSize];
}
else{
font = [UIFont fontWithName:font.fontName size:self.fontSize];
}
attributeStrModel.attributeStr.yy_font = font;
attributeStrModel.attributeStr.yy_color = LZA3AABEColor;
//去掉超链接的下划线
NSURL *link = [attrs objectForKey:NSLinkAttributeName];
if (link) {
attributeStrModel.attributeStr.yy_underlineStyle = NSUnderlineStyleNone;
}
}
[wself.attributeStrArr addObject:attributeStrModel];
}];
[self getAttributeStrWithOpenState:YES];
[self getAttributeStrWithOpenState:NO];
[self getImgUrlArrWithHTMLStr:htmlStr];
});
}
#pragma mark -- 获取所有的图片URL并加载
- (void)getImgUrlArrWithHTMLStr:(NSString *)htmlStr
{
[self.imgUrlStrArr removeAllObjects];
NSData *data = [htmlStr dataUsingEncoding:NSUTF8StringEncoding];
TFHpple *xpathParser = [[TFHpple alloc]initWithHTMLData:data];
// 获取所有的图片链接
NSArray *elements = [xpathParser searchWithXPathQuery:@"//img"];
for (TFHppleElement *element in elements) {
if (element.attributes[@"src"]) {
[self.imgUrlStrArr addObject:element.attributes[@"src"]];
}
}
//加载图片
__weak typeof(self) wself = self;
for (NSString *imgUrlStr in self.imgUrlStrArr) {
//取出URL路径最后面的图片名称
NSString *imgName = [[[imgUrlStr componentsSeparatedByString:@"?"] firstObject] lastPathComponent];
imgName = [imgName componentsSeparatedByString:@"."].firstObject;
NSURL *imgUrl = [NSURL URLWithString:imgUrlStr];
SDWebImageManager *manager = [SDWebImageManager sharedManager] ;
[manager loadImageWithURL:imgUrl options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
} completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
if (image) {
for (AttributedStrModel *strModel in wself.attributeStrArr) {
if (strModel.type == ImageAttributedStrType) {
//比对图片名称是否一致
if ([strModel.imgName isEqualToString:imgName]) {
strModel.image = image;
[wself getAttributeStrWithOpenState:YES];
break;
}
}
}
}
}];
}
}
#pragma mark -- 获取展开和关闭的富文本内容
- (void)getAttributeStrWithOpenState:(BOOL)isOpen
{
if (!self.attributeStrArr.count) {
return;
}
//拼接要显示的字符串
NSMutableAttributedString *attributeStrM = [[NSMutableAttributedString alloc]init];
for (AttributedStrModel *strModel in self.attributeStrArr) {
//收起状态下只拼接文本
if (strModel.type == TextAttributedStrType) {
[attributeStrM appendAttributedString:strModel.attributeStr];
}
//展开状态下且图片已加载完成则拼接上图片
else if (strModel.type == ImageAttributedStrType && strModel.image && isOpen){
//等比缩放
CGFloat imageW = self.imageWidth;
CGFloat imageH = self.imageWidth / strModel.image.size.width * strModel.image.size.height;
NSMutableAttributedString *attachText = [NSMutableAttributedString yy_attachmentStringWithContent:strModel.image contentMode:UIViewContentModeScaleAspectFill attachmentSize:CGSizeMake(imageW, imageH) alignToFont:[UIFont systemFontOfSize:self.fontSize] alignment:YYTextVerticalAlignmentCenter];
[attributeStrM appendAttributedString:attachText];
}
}
attributeStrM.yy_lineSpacing = self.textLineSpacing;
attributeStrM.yy_paragraphSpacing = self.paragraphSpacing;
//添加点击 所有内容 实现展开关闭事件
__weak typeof(self) wself = self;
[attributeStrM yy_setTextHighlightRange:NSMakeRange(0, attributeStrM.length) color:[UIColor blackColor] backgroundColor:nil tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {
if (wself.openCloseBlock) {
wself.openCloseBlock();
}
}];
//添加点击 超链接 & 点击图片 的回调
[attributeStrM enumerateAttributesInRange:NSMakeRange(0, attributeStrM.length) options:0 usingBlock:^(NSDictionary * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
NSURL *link = [attrs objectForKey:NSLinkAttributeName];
//有超链接
if (link) {
attributeStrM.yy_color = [UIColor whiteColor];
[attributeStrM yy_setTextHighlightRange:range color:DecColorFromRGB(204,168,90) backgroundColor:nil tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {
if (wself.linkClickedBlock) {
wself.linkClickedBlock(link.absoluteString);
}
}];
}else{
attributeStrM.yy_color = LZA3AABEColor;
}
YYTextAttachment *attachment = [attrs objectForKey:YYTextAttachmentAttributeName];
//图片不为空
if (attachment) {
[attributeStrM yy_setTextHighlightRange:range color:nil backgroundColor:nil tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {
if (wself.imageClickedBlock) {
wself.imageClickedBlock(attachment.content);
}
}];
}
}];
if (isOpen) {
self.openStr = attributeStrM;
}
else{
self.closeStr = attributeStrM;
}
}
#pragma mark -- LazyLoad
- (NSMutableArray *)attributeStrArr
{
if (!_attributeStrArr) {
_attributeStrArr = [[NSMutableArray alloc]init];
}
return _attributeStrArr;
}
- (NSMutableArray *)imgUrlStrArr
{
if (!_imgUrlStrArr) {
_imgUrlStrArr = [[NSMutableArray alloc]init];
}
return _imgUrlStrArr;
}
@end