关于UITextField实现#话题#的功能

开篇点题,还是先骂两句产品经理,你%@!#@!……#@!&……#@!……!其实主要就是记录一下走的弯路,以便以后能够避开这些坑!首先说一下功能需求,产品经理原话就是模仿新浪微博实现一个话题功能,在发布的时候不需要可点击,只需要变色,显示的时候暂时实现变色,以后实现可点击!

实现可点击自然会想到coreText,如果只实现变色,就单纯使用AttributedString就可以了~~
首先自然是排除for循环去查找匹配,不管什么原因,反正看到用for循环查找就觉得蠢!然后就想到正则表达式!思路到这个地方都还是没有跑偏!
接下来就是到底要在哪个位置去设置我们的AttributedString。于是坑点就来了。
首先是想到UITextfield的delegate。

//即将开始编辑
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField;
//开始编辑
- (void)textFieldDidBeginEditing:(UITextField *)textField;
//即将结束编辑
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField;
//结束编辑
- (void)textFieldDidEndEditing:(UITextField *)textField;
//编辑中
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;

对着这几个代理看了半天,发现也只有最后一个像!要搞事情貌似只能放这儿里面!不得不承认,在这个地方耽误了不是一星半点的时间,因为之后在这里无论如何设置,都差点儿意思!话先说这儿。顺着思路接着搞,接下来就是将textfield.text里的话题内容搞出来!这里话就不多说了,正则表达式,前面讲到了,网上相关内容也一大把,百度,google自己看。
这里贴出代码

//通过正则表达式获取需要改变颜色的部分
+ (NSArray *)cutForAttributedStringWithMainString:(NSString *)str andPattern:(NSString *)pattern
{
    NSString *searchText = str;
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];
    NSArray * strArray = [regex matchesInString:searchText options:0 range:NSMakeRange(0, [searchText length])];
    NSMutableArray * resArray = [NSMutableArray array];
    for (NSTextCheckingResult* b in strArray)
    {
        NSString * resStr = [searchText substringWithRange:b.range];
        [resArray addObject:resStr];
    }
    return [resArray copy];
}
//通过上面得到的变色字段数组,及所在的字符串,将话题字段提亮
+ (NSMutableAttributedString *)getSurplusStringByCutStringArray:(NSArray *)array andMainString:(NSString *)mainStr
{
    NSMutableAttributedString *AttributedString = [[NSMutableAttributedString alloc] initWithString:mainStr];
    for (int i = 0; i< array.count; i++) {
        NSString * str = array[i];
        NSRange range = [mainStr rangeOfString:str];
        NSDictionary * AttributedStringDict = @{
                                                //描述文字颜色
                                                NSForegroundColorAttributeName : [UIColor blueColor] ,
                                                //描述文字字体
                                                NSFontAttributeName : [UIFont systemFontOfSize:15.0f],
                                                //描述文字行距
                                                NSBaselineOffsetAttributeName : [NSNumber numberWithFloat:0.0] ,
                                                //描述文字间距
                                                NSKernAttributeName : [NSNumber numberWithFloat:0.0]
                                                };
        [AttributedString addAttributes:AttributedStringDict range:range];
    }
    return AttributedString;
}

到这里,我们就获得了所需要的AttributedString了!
但是当我们将这段代码拿到UITextfield里去赋值的时候,我们发现,妈的!坑来了!
在UITextfield输入的时候,并不是我们键入什么,就是我们想要得到的字符,它是先预输入一段文字,这段文字是一个选中状态,而键盘上的ToolBar里才是我们想要得到的文字,我们想要的结果,恰恰也是结果文字,而不是包含这段选中状态的字符,代理里,无论是textfield还是string都会包含这段选中状态文字!于是我在这里就卡了很久,脑袋里就想着通过这个代理来搞定这段选中状态文字!
绕过这个坑,就看到希望了!如果我们直接忽略这个选中状态多好!如果我们能直接拿到didChange状态的文字岂不更美!
爬出这两个坑!就是最终结果!
1.首先拿到didChange!

[_textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

2.忽略选中状态的文字

- (void)textFieldDidChange:(UITextField *)textField
{
// 未选中状态文字范围
    UITextRange *rang = textField.markedTextRange; 
    if (rang == nil) { 
        textField.attributedText = [YHAttributedStringTool getDisplayStringWithText:textField.text];
    }
}

接下来还有一件事,就是在删除或者在文字中间加入编辑时会出现光标移位的情况,解决办法是给textField添加一个分类,增加一个像textView的selectedRange,用于记录富文本赋值前的光标位置记录,在赋值后设置其光标位置,关于这个分类网上很多,就不多说了,贴代码

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

推荐阅读更多精彩内容