美文网首页iOS Developer
关于UITextField实现#话题#的功能

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

作者: 燃燃爸爸 | 来源:发表于2017-02-13 14:39 被阅读0次

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

    实现可点击自然会想到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);
    }
    

    相关文章

      网友评论

        本文标题:关于UITextField实现#话题#的功能

        本文链接:https://www.haomeiwen.com/subject/eqwzittx.html