好久沒寫文章了,荒廢了一段時間,今天來寫一個退格刪除@xxx的小文章!
想必大家都用過,就是在使用微信或者QQ群聊的時候,你@xxx的時候,退格了,@xxx直接消失了,大概就是這么一個效果。
注:
最近在自學(xué)swift,所以這次的代碼是用swift寫的,因為剛上手一個周的swift,如果代碼寫得很難看請見諒!
其實(shí)寫法還是跟Objective-C差不多,看大概也能看得懂!
實(shí)現(xiàn)這個效果最主要的就是用到這個UITextFieldDelegate中的一個方法:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange,
replacementString string: String) -> Bool
1.先判斷在輸入框輸入@彈出聯(lián)系人列表的情況
這里如果用戶輸入@,這里彈出聯(lián)系人列表選擇
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類型,記錄此時輸入光標(biāo)的位置
self.remarkText是String類型,記錄此時的UITextField的text值
2.接著說明選擇聯(lián)系人之后的返回情況
我這里返回聯(lián)系人用String表示聯(lián)系人姓名,如果一次選擇了多個用戶我會用 "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記錄當(dāng)前位置
nameArray是聯(lián)系人數(shù)組,因為我用的是String字符串,所以這里分割成數(shù)組,以","分割
然后循環(huán)nameArray聯(lián)系人數(shù)組,把里面的名稱xxx -> @xxx
這里我新建一個可變字典,記錄這個聯(lián)系人的字符串 長度,起始位置,終點(diǎn)位置,ID(聯(lián)系人ID,我這邊是用于上傳給服務(wù)器)
最后是這個可變字典以startLocation排序,最小的在最前面,賦值給textField即可。
3.最后是在輸入框輸入或者刪除的情況
這里有幾種情況,分別是
3.1 在@xxx后面點(diǎn)擊退格操作,這個時候需要刪除@xxx字符串,并且對后方的@yyy結(jié)構(gòu)里面的起始位置和終點(diǎn)位置進(jìn)行前移
3.2 在@xxx中間添加或者退格操作,首先先把這個@xxx的字典刪除,這里已經(jīng)破壞了@xxx這個結(jié)構(gòu),而且@xxx后面的@yyy,@zzz(如果存在的話),需要對所屬字典的起始位置和終點(diǎn)位置進(jìn)行前進(jìn)或者退格
3.3 在@xxx結(jié)構(gòu)前面或者后面進(jìn)行添加操作或者退格操作,這里跟3.2類似,就是輸入光標(biāo)后面的@xxx結(jié)構(gòu)里面的起始位置和終點(diǎn)位置進(jìn)行前進(jìn)或者退格操作
注:這里是接著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記錄當(dāng)前的光標(biāo)位置
然后循環(huán)判斷可變字典數(shù)組(就是擁有多少個@xxx)
第一個if條件是:
在@xxx位置點(diǎn)擊退格,就刪除@xxx字符串,然后把后面的@yyy結(jié)構(gòu)中起始和終點(diǎn)位置分別前移@xxx字符串的長度
第二個if條件是:
在@xxx結(jié)構(gòu)當(dāng)中添加或者退格操作,導(dǎo)致此結(jié)構(gòu)破壞,然后對后續(xù)的@yyy結(jié)構(gòu)進(jìn)行前進(jìn)或者后移操作
如果都不存在這個情況,就是在@xxx結(jié)構(gòu)前面或者后面進(jìn)行添加或者退格操作,這個時候就循環(huán)一次,找到光標(biāo)后的第一個@xxx結(jié)構(gòu),然后進(jìn)行前移或者后退操作。
注:這里string.characters.count == 0代表退格操作,在Objective-C那邊就是string.length == 0的意思!還有,這里沒有全選刪除操作的判斷,如果這里進(jìn)行全選刪除的話,記錄的聯(lián)系人ID不會操作!
具體的效果圖就不上了,就寫到這里了。