好久没写文章了,荒废了一段时间,今天来写一个退格删除@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不会操作!
具体的效果图就不上了,就写到这里了。