在使用UITextView的时候, 如何在光标的位置插入字符 或者 图片? 以下Demo为你解答:

应用背景:键盘自定义emoji表情

#pragma mark - KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
//    NSString *newFaceName = change[@"new"];
    NSString *newFaceName = [change objectForKey:NSKeyValueChangeNewKey];
    
    if (!newFaceName || [newFaceName isKindOfClass:[NSNull class]]) {
        return;
    }
    // 在光标位置插入表情
    [self textWithString:newFaceName];
//    [self attributedTextWithString:newFaceName];
    
} #pragma mark - text && attributedText
- (void)textWithString:(NSString *)newFaceName
{     // 1.1 获取当前输入的文字
    NSMutableString *string = [NSMutableString stringWithString:_txView.text];
    
    // 1.2 获取光标位置
    NSRange rg = _txView.selectedRange;
    if (rg.location == NSNotFound) {
        
        // 如果没找到光标,就把光标定位到文字结尾
        rg.location = _txView.text.length;
    }
    
    // 1.3 替换选中文字
    [string replaceCharactersInRange:rg withString:newFaceName];
    
    _txView.text = string;
    
    // 1.4 定位光标
    _txView.selectedRange = NSMakeRange(rg.location + newFaceName.length, 0);
} // _txView.attributedText  && 虽然能在发送微博时显示图片
// 但是由于plist 文件中的 png名字与官方不一样
// 所以发送出去的内容微博不能识别 emoji 表情
- (void)attributedTextWithString:(NSString *)newFaceName
{     // 1.1 获取当前输入的文字
    NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] init];
    // 1.1.1 拼接之前的文字(图片和文字)
    [attributedText appendAttributedString:_txView.attributedText];
    
    // 1.2 获取光标位置
    NSRange rg = _txView.selectedRange;
    if (rg.location == NSNotFound) {
        
        // 如果没找到光标,就把光标定位到文字结尾
        rg.location = _txView.text.length;
    }
    
    // 1.3 替换选中文字
    // 1.3.1 加载图片
    NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
    attachment.image = [UIImage imageNamed:newFaceName];
    CGFloat attchWH = _txView.font.lineHeight;
    attachment.bounds = CGRectMake(0, -3, attchWH, attchWH);
    
    NSAttributedString *attributedString = [NSAttributedString attributedStringWithAttachment:attachment];
    
    // 1.3.2 拼接图片
    [attributedText insertAttributedString:attributedString atIndex:rg.location];
    
    // 1.3.3 设置字体大小,_txView.font--> null ?!
//    NSRange range = NSMakeRange(0, attributedText.length);
//    [attributedText addAttribute:NSFontAttributeName value:_txView.font range:range];
    
    // 1.3.4 替换文字
    _txView.attributedText = attributedText;
    
    // 1.4 定位光标
    _txView.selectedRange = NSMakeRange(rg.location + 1, 0);
}

利用KVO监听输入的emoji表情

if (!_faceView) {
_faceView = [[FaceView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 0)]; [_faceView.faceImgView addObserver:self forKeyPath:kFaceNameKVO options:NSKeyValueObservingOptionNew context:nil];
}

部分Demo:GitHub FaceViewDemo


UITextView 光标定位的更多相关文章

  1. UITextField限制中英文字数和光标定位以及第三方输入限制问题

    先自定义一个UITextField的子类HLNavTextField,在控制器里调用子类的- (void)limitHansLength:(int)hans otherLength:(int)othe ...

  2. input长度随输入内容动态变化 input光标定位在最右侧

    <input type="text" onkeydown="this.onkeyup();" onkeyup="this.size=(this. ...

  3. input输入框的光标定位的问题

    input输入框的光标定位的问题 在给input输入框赋值的时候,或者在我之前写模拟下拉框js组件的时候,时不时会碰到光标的小bug问题,比如键盘中的 上移或者下移操作,在浏览器中光标会先移到最前端, ...

  4. js实现类似微信网页版在可编辑的div中粘贴内容时过滤剪贴板的内容,光标始终在粘贴内容后面,以及将光标定位到最后的方法

    过滤剪贴板内容以及定位可编辑div光标的方法: <!DOCTYPE html><html lang="en"><head>  <meta ...

  5. 可编辑div,将光标定位到文本之后

    类似qq回复一样,某人评论之后,在对评论进行回复之后,将光标定位到文本之后: function set_focus() { el=document.getElementById('guestbook_ ...

  6. JS控制光标定位,定位到文本的某个位置

    这是一个数字密码,要能够智能的跳转到文本的某个位置,就需要通过JS来控制跳转! 1.onkeyup监听 <input class="put" id="number- ...

  7. TextBox光标定位到文本末尾

    private void RichTextBox1_TextChanged(object sender, EventArgs e) { this.richTextBox1.Select(richTex ...

  8. contenteditable 光标定位到最后

    在Vue做项目时,做了一个div[contenteditable=true]的组件作为文本输入框 在非手动输入值后,光标会丢失,经测试以下这段代码可用,直接将光标定位到最后 function keep ...

  9. IOS textView获取光标定位,以及选中

    当textview成为第一响应者的时候就会调用一个协议方法 - (void)textViewDidChangeSelection:(UITextView *)textView; 在这个协议方法中可以实 ...

随机推荐

  1. Windows ->> Windows下安装MSI程序遇到2503和2502错误

    三个步骤可以解决这个问题: 1) 以管理员身份开启命令行模式并键入msiexec /package <msi文件路径> 2) 修改组策略 计算机配置 ->> 管理模板 -> ...

  2. Windows下Git服务端和客户端的搭建

    1.服务器端的搭建 本人使用的是一款带源码的工具:bonobogitserver,对应的网址为:https://bonobogitserver.com/ 具体操作方式如下: 1.打开网址,下载最新版本 ...

  3. join语句中on条件与where条件的区别

    大纲:on是在生成连接表的起作用,where是生成连接表之后对连接表再进行过滤 当使用left join时,无论on的条件是否满足,都会返回左表的所有记录,对于满足的条件的记录,两个表对应的记录会连接 ...

  4. Django路由系统---django重点之url命名分组

    django重点之url命名分组[参数无顺序要求]. settigs.py:增加STATICFILES_DIRS静态资源路径配置,名称为创建的文件夹名称 'DIRS': [os.path.join(B ...

  5. Linu下的Mysql学习详解_【all】

    Linux下Mysql简介 1.什么是Mysql(MariDB) 1.数据库:存储数据的仓库    2.关系型数据库:mysql(主流用5.5,5.6), oracle        本质:二维表   ...

  6. Centos 安装 Oracle Java JDK

    Centos 安装 jdk 创建目录,用来存放下载的 JDK cd /usr/local mkdir -p tools cd tools 下载JDK,后边的下载地址你可以到 orcal 官网去获取最新 ...

  7. 中间人攻击利用框架bettercap测试

    0x00前言 上篇提到内网渗透很有趣,这次就从一款新工具说起: bettercap 0x01简介 bettercap可用来实现各种中间人攻击,模块化,便携.易扩展 0x02特点 提到中间人攻击,最知名 ...

  8. memcached源码剖析4:并发模型

    memcached是一个典型的单进程系统.虽然是单进程,但是memcached内部通过多线程实现了master-worker模型,这也是服务端最常见的一种并发模型.实际上,除了master线程和wor ...

  9. IOS Charles(代理服务器软件,可以用来拦截网络请求)

    什么是Charles Charles是一款代理服务器软件,可以用来拦截网络请求 利用Charles能得知大部分公司app的数据来源和数据格式 下载地址:http://www.charlesproxy. ...

  10. angularJs的作用域和依赖注入

    一.angularJs的作用域 &scope这是局部作用域,先在局部作用域中找,如果没有就在全局作用域中找  &rootScope这是全局作用域 <!DOCTYPE HTML&g ...