iOS 富文本之图文混排(插入图片上传到服务器)

第一版,以实现功能为主,相比较简陋一点,多多包含,先上效果图


9918146F-3D83-40BA-80EB-359D06594273.png

1.先修改键盘上的工具栏

self.contentView.inputAccessoryView = [self createInputAccessoryView];
//键盘上的工具栏
- (UIView *)createInputAccessoryView {
    // 相机
    UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"edit_pic"] style:UIBarButtonItemStylePlain target:self action:@selector(item1Action)];
    //收起键盘
    UIBarButtonItem *th1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(cancleClick)];
    //两个item之间的间距
    UIBarButtonItem *th2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    th1.tintColor = [UIColor blackColor];
    
    UIToolbar *tool = [UIToolbar new];
    [tool sizeToFit];
    [tool setItems:@[item1,th2,th1]];
    return tool;
}

2.相机的点击事件,也就是图片上传服务器的方法

//工具栏的点击事件
- (void)item1Action {

首先将图片上传到你们的服务器(这里需要图片和url)
 
NSTextAttachment* textAttachment = [[NSTextAttachment alloc] init];
//userInfo这个属性需要写延展,在下面
textAttachment.userInfo = 图片的URL;
//照片赋值
textAttachment.image = image;
//设置图片的大小
textAttachment.bounds = CGRectMake(0, 0, myWidth/2, myWidth/2);
//类型转换
NSAttributedString* imageAttachment = [NSAttributedString attributedStringWithAttachment:textAttachment];
NSMutableAttributedString *attriStr = [self.contentView.attributedText mutableCopy];
//获取光标的位置
NSRange range = self.contentView.selectedRange;
//插入
[attriStr insertAttributedString:imageAttachment atIndex:range.location];
//拼接
//[attriStr appendAttributedString:imageAttachment];
self.contentView.attributedText = attriStr; 

}

3.上传服务器的相关操作

正常来说,直接富文本文字转换成HTML格式的字符串上传服务器就可以了。如果没有特殊要求,
上传字符串到服务器就告一段落了。

我们这后台特殊要求,需要转换成字符串,然后图片链接拼接到相对应的位置(可以选择性忽略)
NSString *textStr = [[self textStringWithSymbol:@"[图片]" attributeString:self.contentView.attributedText] mutableCopy];
    int index = 0;
    //通过替换
    if (textStr.length > 3) {
        for (int i = 0; i <= textStr.length - 4; i ++) {
            NSString *tempStr = [textStr substringWithRange:NSMakeRange(i, 4)];
            if ([tempStr isEqualToString:@"[图片]"]) {
                NSString *imgStr = [NSString stringWithFormat:@"<p><img src=\"%@\"></p>",self.imgArray[index]];
                textStr = [textStr stringByReplacingCharactersInRange:NSMakeRange(i, 4) withString:imgStr];
                index ++;
            }
        }
    }

执行上传服务器的操作。
textStr 就是最终上传上传服务器的文本。

下面的方法是将富文本转换成纯文本的信息

/** 将富文本转换为带有图片标志的纯文本*/
- (NSString *)textStringWithSymbol:(NSString *)symbol attributeString:(NSAttributedString *)attributeString{
    NSString *string = attributeString.string;
    //调用的方法在下面
    string = [self stringDeleteString:@"\n" frontString:@"[图片]" inString:string];
    //最终纯文本
    NSMutableString *textString = [NSMutableString stringWithString:string];
    //替换下标的偏移量
    __block NSUInteger base = 0;
    
    //遍历
    [attributeString enumerateAttribute:NSAttachmentAttributeName inRange:NSMakeRange(0, attributeString.length)
                                options:0
                             usingBlock:^(id value, NSRange range, BOOL *stop) {
                                 //检查类型是否是自定义NSTextAttachment类
                                 if (value && [value isKindOfClass:[NSTextAttachment class]]) {
                                     //替换
                                     [textString replaceCharactersInRange:NSMakeRange(range.location + base, range.length) withString:symbol];
                                     //增加偏移量
                                     base += (symbol.length - 1);
                                     //将富文本中最终确认的照片取出来
                                     NSTextAttachment *attachmentImg = (NSTextAttachment *)value;
                                    //将图片存入数组,后面需要用到
                                     [self.imgArray addObject:attachmentImg.userInfo];
                                 }
                             }];
    
    return textString;
}
/** 删除字符串*/
- (NSString *)stringDeleteString:(NSString *)deleteString frontString:(NSString *)frontString inString:(NSString *)inString{
    NSArray *ranges = [self rangeOfSymbolString:frontString inString:inString];
    NSMutableString *mutableString = [inString mutableCopy];
    NSUInteger base = 0;
    for (NSString *rangeString in ranges) {
        NSRange range = NSRangeFromString(rangeString);
        [mutableString deleteCharactersInRange:NSMakeRange(range.location - deleteString.length + base, deleteString.length)];
        base -= deleteString.length;
    }
    return [mutableString copy];
}
/** 统计文本中所有图片资源标志的range*/
- (NSArray *)rangeOfSymbolString:(NSString *)symbol inString:(NSString *)string {
    NSMutableArray *rangeArray = [NSMutableArray array];
    NSString *string1 = [string stringByAppendingString:symbol];
    NSString *temp;
    for (int i = 0; i < string.length; i ++) {
        temp = [string1 substringWithRange:NSMakeRange(i, symbol.length)];
        if ([temp isEqualToString:symbol]) {
            NSRange range = {i, symbol.length};
            [rangeArray addObject:NSStringFromRange(range)];
        }
    }
    return rangeArray;
}

以上是转换成纯文本,然后拼接上url操作,可以选择性忽略。
4.NSTextAttachment 延展,为NSTextAttachment添加一个属性(关键操作)

.h文件
#import <UIKit/UIKit.h>
@interface NSTextAttachment (LMText)
//添加一个属性
@property (nonatomic, strong) id userInfo;

@end

//.m文件
#import "NSTextAttachment+LMText.h"
#import <objc/runtime.h>
@implementation NSTextAttachment (LMText)
static void * keyOfUserInfo = &keyOfUserInfo;
//实现它的set,get方法
- (id)userInfo {
    return objc_getAssociatedObject(self, keyOfUserInfo);
}

- (void)setUserInfo:(id)userInfo {
    objc_setAssociatedObject(self, keyOfUserInfo, userInfo, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

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

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,021评论 8 265
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 姐姐微信说,她把工作辞掉了,就想先好好歇一歇,哪怕看看景呢。 今天去图书馆借书,想起姐姐家就在附近便喊她一起出来了...
    某只璐阅读 257评论 0 0
  • 因为有了你 我才变得期待明天 明天也选择接纳我的今天
    宋禾初阅读 147评论 0 0