iOS图文混排-模仿石墨文档文档编辑器(踩坑篇)

图文混排实现

最近公司的项目需要用到图文混排编辑来书写个人简介,由于需求功能比较简单,所以找到了SimpleWord,个人感觉功能还是很强大的,但在实现需求过程中发现了一些问题,特此记录一下。

踩坑

1、在web上正常加载的图片(图1),通过富文本的下面的方式显示在textView上会出现图片宽高不适配的情况,如图2所示;

textView.attributedText = [[NSAttributedString alloc] initWithData:[autoStr dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];

图1 - web上显示的样式


图1 - textView上显示的样式

2、由于图片都是网络图片,显示在textView上如果不对图片进行修改,点击保存,用SimpleWord写好的的方法将原生的 AttributedString 导出成 HTML的方式,会存在<img src="null"/>的问题。

填坑

1、针对第一个问题,我将得到的html加上img的css样式,代码如下,完美解决图片不适配的问题!

NSString *autoStr = [NSString stringWithFormat:@"<head><style>img{width:%f !important;height:auto}</style></head>%@",SCREENW - 2*20,_htmlString];

NSAttributedString *attributedText = [[NSAttributedString alloc] initWithData:[autoStr dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];

2、针对第二个问题,图片标签src="null"的问题,这个问题还是困惑了很久的,后来通过查看他将原生的 AttributedString 导出成 HTML的方法,由于代码较长,就贴出导出img的方法;

    可以分析得出导出img的思路是获取attributes中的NSAttachment类,在拿到NSAttachment的userInfo属性,但这个userInfo是NSAttachment的分类属性,我们转成attributedString时候并没有给他赋初值,所以直接对原来图片进行保存的话,肯定是没有值的!

NSDictionary *attributes = [attributedString attributesAtIndex:effectiveRange.location effectiveRange:&effectiveRange];

NSTextAttachment *attachment = attributes[@"NSAttachment"];

NSParagraphStyle *paragraph = attributes[@"NSParagraphStyle"];

LMParagraphConfig *paragraphConfig = [[LMParagraphConfig alloc] initWithParagraphStyle:paragraph type:LMParagraphTypeNone];

if (attachment) {

switch (attachment.attachmentType) {

case LMTextAttachmentTypeImage: // attachment.fileWrapper.preferredFilename

[htmlContent appendString:[NSString stringWithFormat:@"<img src=\"%@\" width=\"100%%\"/>", attachment.userInfo]];

break;

default:

break;

}

}

找到问题之后,接下来就是解决了,现在要做的就是在原来attributedString的基础上取出NSTextAttachment,并给其userInfo属性赋上我们的图片地址;参照图片生成NSTextAttachment 的方法

- (NSTextAttachment *)insertImage:(UIImage *)image;

我们在得出修改后的富文本字符串之前,我们要先拿到所有的img标签,在这里我用的是Hpple

+ (NSArray *)getSrcArrWithHtmlString:(NSString *)htmlString {

NSData *data =[htmlString dataUsingEncoding:NSUnicodeStringEncoding];

NSString *result = [[NSString alloc] initWithData:data  encoding:NSUTF8StringEncoding];  //data转字符串 为了打印不是乱码

SLog(@"------%@",result);

TFHpple *Hpple = [[TFHpple alloc]initWithHTMLData:data];

NSArray *array =[Hpple searchWithXPathQuery:@"//img"]; //获取到为img标签数组

NSMutableArray *secArr = [NSMutableArray array];

for (TFHppleElement *HppleElement in array) {

NSDictionary *node = HppleElement.attributes;

[secArr addObject:node[@"src"]];

}

return secArr;

}


最后,我们可以得出修改后的富文本字符串,大致代码如下;

// 改变attachment.userInfo

+ (NSAttributedString *)attStringFromAttributedString:(NSAttributedString *)attributedString textView:(UITextView *)textView htmlString:(NSString *)htmlString {

NSMutableAttributedString *copyAttr = [[NSMutableAttributedString alloc] initWithAttributedString:attributedString];

NSRange effectiveRange = NSMakeRange(0, 0);

int section = 0;

NSArray *secArr = [self getSrcArrWithHtmlString:htmlString];

while (effectiveRange.location + effectiveRange.length < attributedString.length) {

NSDictionary *attributes = [attributedString attributesAtIndex:effectiveRange.location effectiveRange:&effectiveRange];

NSTextAttachment *attachment = attributes[@"NSAttachment"];

if (attachment) {

attachment.attachmentType = LMTextAttachmentTypeImage;

attachment.userInfo = secArr[section]; // 获取网络图片路径

section++;

//

NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment];

NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:@"\n"];

[attributedStr insertAttributedString:attachmentString atIndex:0];

[attributedStr addAttributes:textView.typingAttributes range:NSMakeRange(0, attributedStr.length)];

// 添加样式

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];

[paragraphStyle setParagraphStyle:[NSParagraphStyle defaultParagraphStyle]];

paragraphStyle.paragraphSpacingBefore = 8.f;

paragraphStyle.paragraphSpacing = 8.f;

[attributedStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, attributedStr.length)];

[copyAttr replaceCharactersInRange:effectiveRange withAttributedString:attributedStr];

}

effectiveRange = NSMakeRange(effectiveRange.location + effectiveRange.length, 0);

}

return copyAttr;

}


PS:由于我这次项目只是简单的图文编辑跟混排,需要的内容不是很多,所以采用NSAttributedString进行展示,如果需要大量的图片及文字展示,例如阅读类的APP,建议还是用coreText或textKit进行排版!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容