坑1:關于UITextField限定長度.
需求很簡單.就是限定一個UITextField的字符長度在n個中文之內(中英文均有可能).
首先,需求中有中英文的要求,那么如何計算長度呢,很簡單:
lengthOfBytesUsingEncoding
1個中文長度等于3個英文長度.在UITextField的代理里面直接搞定它.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSString *strWhenChanged = [textField.text stringByReplacingCharactersInRange:range withString:string];
return [strWhenChanged lengthOfBytesUsingEncoding:NSUTF8StringEncoding] <= 9;
}
似乎好了,測試一下,好像不那么對勁,當字數滿了以后,無法刪除了.
ok,繼續改進
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if ([string isEqualToString:@""]){
return YES;
}
NSString *strWhenChanged = [textField.text stringByReplacingCharactersInRange:range withString:string];
return [strWhenChanged lengthOfBytesUsingEncoding:NSUTF8StringEncoding] <= 9;
}
好了,可以刪除了.到了規定字符數以后也無法繼續輸入.可是,問題又來了,全拼鍵盤的聯想仍然能用.
媽蛋,我們關了它
textfiled.autocorrectionType = UITextAutocorrectionTypeNo;
啊,好像沒用...還是可以聯想.而且有個特別嚴重的問題,點擊聯想的文字,代理并不會觸發!
替換成通知好了,我們使用通知:
UITextFieldTextDidChangeNotification
在使用一個屌屌的屬性:
markedTextRange
就可以啦.
不過還有一個問題,如果規定n個字符,如果超過n個字符是截斷呢還是干脆就置空?截斷似乎要好很多.
我們需要做一個遞歸的截斷方法:
extension String{
func limitLengthByUTF8(limitedLenght: Int) -> String{
if self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) <= limitedLenght{
return self
}
else{
let limitedStr = self.substringToIndex(advance(self.endIndex, -1))
return limitedStr.limitLengthByUTF8(limitedLenght)
}
}
}
最終是這樣的:
[[NSNotificationCenter defaultCenter] addObserverForName:UITextFieldTextDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
UITextField *field = (UITextField *)note.object;
if(field.markedTextRange){
return;
}
field.text = [field.text limitLengthByUTF8:45];
}];
坑在哪里?
流著眼淚的說,我用的是第三方輸入法(百度).測試的時候,這個點根本沒出任何問題.第三方輸入法有自己的toolbar,聯想的時候并不會造成代理不響應的情況.
切記切記,一定在開發中要使用原生的輸入法進行測試啊.
坑2:坑爹的聯系人
又出問題了!怎么問題這么多!
有一個需求是讀取聯系人列表,然后進行各項操作,諸如分類(A-Z),篩選之類的.在分類的時候,使用CFStringTransform獲取聯系人拼音首字母,的確會有一些資源消耗.
在普通情況下,一兩百個聯系人的時候,并沒有明顯的卡頓,所以當時也沒有做異步的操作.
可是,在測試的時候,居然出現了非常明顯的卡頓,這...
遇上bug,首先修改為異步,dispatch_async走起.
然后查詢為何會卡頓.
通過查詢,不可思議的一幕來了:200來個聯系人,居然有3000多個電話號碼!
無法理解,無法理解,繼續抓蟲!
通過打印,發現了如下的情況,在系統電話本中如圖所示:
原來,這就是安全衛士類的軟件(360等)攔截騷擾電話的數據庫.
那么怎么來的呢?很有可能是從其他地方導入.
目前沒有特別好的辦法處理,不知道大家有沒有好的方案?
我暫時只想到2種:
是找尋此種號碼的規律,將其忽略.不過因為樣本不足,此種方法未被采納.有360,還有百度,還有騰訊,未來還有xxx衛士啊.
當單個聯系人中超過n個號碼的話,就判定該聯系人為非正常聯系人.n根據情況設定.當然這種方法有錯殺的風險.
的確有可能有人會把公司當做一個聯系人,所有的同事的聯系方式都建立在該公司(聯系人)下.不過這種方式蠻蠢的,畢竟無法搜索...