实现输入@弹出列表选择,显示@xxx,退格@xxx直接删除效果

好久没写文章了,荒废了一段时间,今天来写一个退格删除@xxx的小文章!
想必大家都用过,就是在使用微信或者QQ群聊的时候,你@xxx的时候,退格了,@xxx直接消失了,大概就是这么一个效果。

注:

最近在自学swift,所以这次的代码是用swift写的,因为刚上手一个周的swift,如果代码写得很难看请见谅!
其实写法还是跟Objective-C差不多,看大概也能看得懂!

实现这个效果最主要的就是用到这个UITextFieldDelegate中的一个方法:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, 
replacementString string: String) -> Bool

1.先判断在输入框输入@弹出联系人列表的情况

这里如果用户输入@,这里弹出联系人列表选择

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        if string == "@" {
            self.location = range.location;
            self.remarkText = textField.text!;
            // Present MemberViewController
            let memberVC: MemberViewController = MemberViewController();
            memberVC.delegate = self;
            memberVC.presentedMemberList = true;
            let naviMemberVC: UINavigationController = UINavigationController.init(rootViewController: memberVC);
            self.presentViewController(naviMemberVC, animated: true, completion: {
                return true;
            });
        }
        else{
            这里是输入或者删除,下面会介绍
        }

self.location是NSInterger类型,记录此时输入光标的位置
self.remarkText是String类型,记录此时的UITextField的text值

2.接着说明选择联系人之后的返回情况

我这里返回联系人用String表示联系人姓名,如果一次选择了多个用户我会用 "xxx,yyy,zzz"字符串表示。

            // Remark Location
            var startLocation: NSInteger = self.location;
            let nameArray: NSArray = name.componentsSeparatedByString(",") as NSArray;
            for index in 0..<nameArray.count {
                let nameValue: String = "@" + (nameArray.objectAtIndex(index) as! String);
                let rangeDictionary: NSMutableDictionary = NSMutableDictionary.init(objects: [nameValue.characters.count, startLocation, startLocation + nameValue.characters.count, IDArray.objectAtIndex(index)], forKeys: ["length", "startLocation", "endLocation", "ID"]);
                self.rangeArray.addObject(rangeDictionary);
                startLocation += nameValue.characters.count;
                self.remarkText += nameValue;
            }
            // Sort RangeArray By Ascend
            self.rangeArray.sortUsingDescriptors(NSArray.init(array: [NSSortDescriptor.init(key: "startLocation", ascending: true)]) as! [NSSortDescriptor]);
            self.textField.text = self.remarkText;

局部变量startLocation记录当前位置
nameArray是联系人数组,因为我用的是String字符串,所以这里分割成数组,以","分割
然后循环nameArray联系人数组,把里面的名称xxx -> @xxx
这里我新建一个可变字典,记录这个联系人的字符串 长度,起始位置,终点位置,ID(联系人ID,我这边是用于上传给服务器)
最后是这个可变字典以startLocation排序,最小的在最前面,赋值给textField即可。

3.最后是在输入框输入或者删除的情况

这里有几种情况,分别是
3.1 在@xxx后面点击退格操作,这个时候需要删除@xxx字符串,并且对后方的@yyy结构里面的起始位置和终点位置进行前移
3.2 在@xxx中间添加或者退格操作,首先先把这个@xxx的字典删除,这里已经破坏了@xxx这个结构,而且@xxx后面的@yyy,@zzz(如果存在的话),需要对所属字典的起始位置和终点位置进行前进或者退格
3.3 在@xxx结构前面或者后面进行添加操作或者退格操作,这里跟3.2类似,就是输入光标后面的@xxx结构里面的起始位置和终点位置进行前进或者退格操作

注:这里是接着UITextFieldDelegate那个方法的else

            let currentLocation: NSInteger = range.location;
            for index in 0..<self.rangeArray.count {
                let tempDic: NSMutableDictionary = self.rangeArray.objectAtIndex(index) as! NSMutableDictionary;
                let length: NSInteger = tempDic.objectForKey("length") as! NSInteger;
                let startLocation: NSInteger = tempDic.objectForKey("startLocation") as! NSInteger;
                let endLocation: NSInteger = tempDic.objectForKey("endLocation") as! NSInteger;
                let arrayIndex: NSInteger = tempDic.objectForKey("ID") as! NSInteger;
                
                // Delete
                if currentLocation == endLocation - 1 {
                    var temp: NSString = textField.text! as NSString;
                    temp = temp.stringByReplacingCharactersInRange(NSMakeRange(startLocation, length), withString: "");
                    textField.text = temp as String;
                    // Move Other Location
                    for subIndex in (index+1)..<self.rangeArray.count {
                        let subTempDic: NSMutableDictionary = self.rangeArray.objectAtIndex(subIndex) as! NSMutableDictionary;
                        subTempDic.setObject(subTempDic.objectForKey("startLocation") as! NSInteger - length, forKey: "startLocation");
                        subTempDic.setObject(subTempDic.objectForKey("endLocation") as! NSInteger - length, forKey: "endLocation");
                    }
                    // Delete Data
                    self.rangeArray.removeObjectAtIndex(index);
                    self.userIDArray.removeObject(arrayIndex);
//                    self.userIDArray.removeObjectAtIndex(arrayIndex);
                    return false;
                }
                // Change @xxx Style
                else if currentLocation > startLocation && currentLocation < endLocation {
                    // Delete Content
                    if string.characters.count == 0 {
                        // Move Other Location
                        for subIndex in (index+1)..<self.rangeArray.count {
                            let subTempDic: NSMutableDictionary = self.rangeArray.objectAtIndex(subIndex) as! NSMutableDictionary;
                            subTempDic.setObject(subTempDic.objectForKey("startLocation") as! NSInteger - 1, forKey: "startLocation");
                            subTempDic.setObject(subTempDic.objectForKey("endLocation") as! NSInteger - 1, forKey: "endLocation");
                        }
                        self.rangeArray.removeObjectAtIndex(index);
                        self.userIDArray.removeObject(arrayIndex);
//                        self.userIDArray.removeObjectAtIndex(arrayIndex);
                        return true;
                    }
                    // Add Content
                    else{
                        // Move Other Location
                        for subIndex in (index+1)..<self.rangeArray.count {
                            let subTempDic: NSMutableDictionary = self.rangeArray.objectAtIndex(subIndex) as! NSMutableDictionary;
                            subTempDic.setObject(subTempDic.objectForKey("startLocation") as! NSInteger + string.characters.count, forKey: "startLocation");
                            subTempDic.setObject(subTempDic.objectForKey("endLocation") as! NSInteger + string.characters.count, forKey: "endLocation");
                        }
                        self.rangeArray.removeObjectAtIndex(index);
                        self.userIDArray.removeObject(arrayIndex);
//                        self.userIDArray.removeObjectAtIndex(arrayIndex);
                        return true;
                    }
                }
            }
            // Judge Loop Agagin ?
            for index in 0..<self.rangeArray.count {
                let tempDic: NSMutableDictionary = self.rangeArray.objectAtIndex(index) as! NSMutableDictionary;
                let startLocation: NSInteger = tempDic.objectForKey("startLocation") as! NSInteger;
                if currentLocation < startLocation {
                    // Move Location
                    if string.characters.count == 0 {
                        // Delete Content
                        for subIndex in index..<self.rangeArray.count {
                            let subTempDic: NSMutableDictionary = self.rangeArray.objectAtIndex(subIndex) as! NSMutableDictionary;
                            subTempDic.setObject(subTempDic.objectForKey("startLocation") as! NSInteger - 1, forKey: "startLocation");
                            subTempDic.setObject(subTempDic.objectForKey("endLocation") as! NSInteger - 1, forKey: "endLocation");
                        }
                        return true;
                    }
                    else{
                        // Add Content
                        for subIndex in index..<self.rangeArray.count {
                            let subTempDic: NSMutableDictionary = self.rangeArray.objectAtIndex(subIndex) as! NSMutableDictionary;
                            subTempDic.setObject(subTempDic.objectForKey("startLocation") as! NSInteger + string.characters.count, forKey: "startLocation");
                            subTempDic.setObject(subTempDic.objectForKey("endLocation") as! NSInteger + string.characters.count, forKey: "endLocation");
                        }
                        return true;
                    }
                }
                else{
                    continue;
                }
            }

这里先定义局部变量currentLocation记录当前的光标位置
然后循环判断可变字典数组(就是拥有多少个@xxx)
第一个if条件是:
在@xxx位置点击退格,就删除@xxx字符串,然后把后面的@yyy结构中起始和终点位置分别前移@xxx字符串的长度
第二个if条件是:
在@xxx结构当中添加或者退格操作,导致此结构破坏,然后对后续的@yyy结构进行前进或者后移操作
如果都不存在这个情况,就是在@xxx结构前面或者后面进行添加或者退格操作,这个时候就循环一次,找到光标后的第一个@xxx结构,然后进行前移或者后退操作。

注:这里string.characters.count == 0代表退格操作,在Objective-C那边就是string.length == 0的意思!还有,这里没有全选删除操作的判断,如果这里进行全选删除的话,记录的联系人ID不会操作!

具体的效果图就不上了,就写到这里了。

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

推荐阅读更多精彩内容