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

2016-05-09  本文已影响348人  月咏蝴蝶

好久没写文章了,荒废了一段时间,今天来写一个退格删除@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不会操作!

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

上一篇 下一篇

猜你喜欢

热点阅读