iOS @功能的部分实现思路

需求描述

1. 发布信息时,通过键盘键入@符号,或者点选相关功能键,唤醒@列表,进行选择

2.选择结束后,输入栏改色显示相关内容

3.删除时,整体删除@区块,且不能让光标落在@区块之间

实现步骤

1. 键入@符号,触发相关功能

 1 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
 2     //判断键入的字符
 3     if ([text isEqualToString:@"@"]) {
 4         //触发相关功能
 5         //[self pickRemaidBtnClick];
 6         return NO;
 7     }
 8
 9     return YES;
10 }

2. @区块颜色修改

(1)使用到的正则表达式

#define kATRegular @"@[\\u4e00-\\u9fa5\\w\\-\\_]+ "

(2)获取匹配到的区块下标数组

+ (NSArray *) getMatchsWithStr : (NSString *) text {
    // 找到文本中所有的@
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:kATRegular options:NSRegularExpressionCaseInsensitive error:nil];
    NSArray *matches = [regex matchesInString:text options:NSMatchingReportProgress range:NSMakeRange(0, [text length])];
    return matches;
}

(3)修改文本颜色

-(void)textViewDidChange:(UITextView *)textView {
    NSArray *matchs = [RemaidUserUtils getMatchsWithStr:textView.text];
    //改色
    [textView.textStorage addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithHexString:@"#333333"] range:NSMakeRange(0, textView.text.length)];
    for (NSTextCheckingResult *match in matchs)
    {
        [textView.textStorage addAttribute:NSForegroundColorAttributeName value:BLUECOLOR range:NSMakeRange(match.range.location, match.range.length - 1)];
    }
}

3.删除时整体删除@区块

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{

    if ([text isEqualToString:@""])
    {
        NSRange selectRange = textView.selectedRange;
        if (selectRange.length > 0)
        {
            //用户长按选择文本时不处理
            return YES;
        }

        // 判断删除的是一个@中间的字符就整体删除
        NSMutableString *string = [NSMutableString stringWithString:textView.text];
        NSArray *matches = [RemaidUserUtils getMatchsWithStr:string];

        BOOL inAt = NO;
        NSInteger index = range.location;
        for (NSTextCheckingResult *match in matches)
        {
            NSRange newRange = NSMakeRange(match.range.location + 1, match.range.length - 1);
            if (NSLocationInRange(range.location, newRange))
            {
                inAt = YES;
                index = match.range.location;
                [textView.textStorage replaceCharactersInRange:match.range withString:@""];
                textView.selectedRange = NSMakeRange(index, 0);
                [self textViewDidChange:textView];
                return NO;
                break;
            }
        }
    }

    return YES;
}

4.不允许光标落在@区块之间

- (void)textViewDidChangeSelection:(UITextView *)textView {
    // 光标不能点落在@词中间
    NSRange range = textView.selectedRange;
    if (range.length > 0)
    {
        // 选择文本时可以
        return;
    }

    NSArray *matches = [RemaidUserUtils getMatchsWithStr:textView.text];

    for (NSTextCheckingResult *match in matches)
    {
        NSRange newRange = NSMakeRange(match.range.location + 1, match.range.length - 1);
        if (NSLocationInRange(range.location, newRange))
        {
            if (range.location == match.range.location + 1) {
                textView.selectedRange = NSMakeRange(match.range.location + match.range.length, 0);
            } else {
                textView.selectedRange = NSMakeRange(match.range.location , 0);
            }
            break;
        }
    }
}

BY: chu

原文地址:https://www.cnblogs.com/widgetbox/p/11957484.html

时间: 2024-10-21 09:08:57

iOS @功能的部分实现思路的相关文章

undo/redo功能的原理和思路

一些具有操作记录的系统,如店铺装修.富文本编辑等,都具有undo/redo功能,可实现界面操作过程的撤销和恢复,简述开发undo/redo功能的原理和思路. undo是将用户上一步做的操作对程序造成的改动恢复到改动之前,而redo操作是指重新实现这种改动. undo/redo操作的实现方式分为两类:记录数据和记录操作. 记录数据是指将信息编辑窗口打开时,保存原始数据,然后记录用户每次操作后的结果数据,这里的数据是指信息编辑窗口中所有可能发生变动的数据.做undo操作时程序将用户上一步操作前的数据

李洪强iOS开发-网络新闻获取数据思路回顾

李洪强iOS开发-网络新闻获取数据思路回顾 01 创建一个继承自AFHTTPSessionManager的工具类:LHQNetworkTool 用来发送网络请求获取数据  1.1 定义类方法返回单例对象 1.2 单例的实现,设置baseURL,设置超时时长等 02 创建一个分类, 传入一个类的参数返回一个数组,返回当前类的所有属性 用在模型中处理模型数据 03 创建图片轮播模型(model)类发送请求获取轮播图片的数据  3.1 定义属性: 标题,图片 定义两个类方法: (1)传入一个字典的参数

实现ios常见菜单效果的思路

目前见过的实现边侧菜单的效果,比较流行的有以下三种:(效果图) 1.菜单栏覆盖在部分主视图上 附上实现该效果的一个不错的源码地址: http://code4app.com/ios/RNFrostedSidebar/524399706803fa3c33000001 (1)最开始要实现这个效果,我想最简单的方式就是:添加UIView,加上一个self.view大小的子视图,菜单列表以外的区域设为透明灰色.后来发现,如果当前的控制器有显示导航栏或者工具栏,这个子视图就无法遮盖住导航栏或者工具栏上面的按

度量快速开发平台中“导入”功能的一般实现思路

度量快速开发平台中,"导入"功能在很多业务中都会用到.一般是在其他系统或者人为整理好的数据,比如要导入基础的数据,比如要在另外的系统中导入工资信息等.导入功能,一般是与管理界面相匹配可进行的.我们常用的实现思路是,首先做好一个管理界面,比如按照条件查询出数据来.下图是一个在职人员工资情况的管理界面,该功能是在办公管理系统中制作人员的工资数据,然后每个人可以查阅自己的工资. 人员工资本身是在财务系统中编制好的,并且从财务系统中导出为xls的文件. 在"导入"按钮上,打

Html、Flex、Android、JavaGUI、IOS前端开发的总体思路比较

前端开发,主要解决2大方面,一是界面展现(容器+控件+布局定位),二是对界面事件的逻辑处理(事件响应+服务器交互),Html.Flex.Android思路相似,JavaGUI.IOS思路相似,只要熟悉其中一种,就可以举一反三,轻松入门. 前端技术 界面布局 逻辑处理 Html html标签 javascript代码 Flex mxml标签 actionscript代码 Android xml标签 Java代码 JavaGUI Java代码 Java代码 IOS Objective-C代码 Obj

怎么样才是设计功能函数的好思路(javascript)?

在js里面,对于函数的调用,实际上也是也是面向对象的思路,于是写好js函数,也是考核面向对象设计的能力,同时也必须考虑到如何实现高内聚和低耦合,拿一个例子来说,现在的需求是这样的,实现个投资进度框,就是如图所示:总共分四步来走,第一步“创建订单中”,成功改变提示信息“创建订单成功!”,显示,不成功改变提示信息“创建订单失败!”,显示,依次下去第二步,第三步,第四步! 我的dom结构是这样的: <!--投资操作进度tip--> <div class="invest_progres

ios多种语言的本地化思路

多语言在应用程序中一般有两种做法: 一.程序中提供给用户自己选择的机会: 二.根据当前用户当前移动设备的语言自动将我们的app切换对应语言. 第一种做法比较简单完全靠自己的发挥了,这里主要讲第二种做法,主要分一下几点: 1.本地化应用程序名称 2.本地化字符串 3.本地化图片 4.本地化其他文件 1.本地化应用程序名称 (1)点击"new file"然后在弹出窗口左侧选择IOS的resource项,在右侧就可以看到"String File"的图标.创建这个文件,命名

iOS中的模块化开发思路一

我想不光是在iOS开发中,在其他各种软件产业开发中,模块化开发是必不可少的一种开发模式. 那么,在iOS中如何做到模块化开发.小伙伴们之间并行的有规矩的开发.集成.代码了?答案是,设计模式出.依赖抽象,不依赖具体实现. 第一步,拿到每一个模块的开发任务的小伙伴们,首先不要马上去写各种viewController.subViews.networkApi.dataBaseApi.entity.... .我想的是,我们应该定义一下接口,告诉其他调用这个模块的小伙伴们,我们这个模块能够干一些什么...

php LBS(附近地理位置)功能实现的一些思路

在开发中经常会遇到把数据库已有经纬度的地方进行距离排序然后返回给用户 例如一些外卖app打开会返回附近的商店,这个是怎么做到的呢? 思路一: 根据用户当前的位置,用计算经纬度距离的算法逐一计算比对距离,然后进行排序.这里可以参考下面这个算法: <?php /** * 查找两个经纬度之间的距离 * * @param $latitude1 float 起始纬度 * @param $longitude1 float 起始经度 * @param $latitude2 float 目标纬度 * @para