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

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

作者: 月咏蝴蝶 | 来源:发表于2016-05-09 15:43 被阅读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不会操作!

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

    相关文章

      网友评论

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

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