問題提出
最近趁着放假時間,在看The Big Nerd Ranch的iOS編程,想着重新複習一遍iOS開發的基礎知識
書中第四章有一個温度轉換的app實現,整體實現並不難
其中有個問題——如何利用UITextFieldDelegate委託限制UITextField的輸入
問題背景
UITextFieldDelegate裏面有個函數
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
簡單來説,就是通過這個函數處理輸入的請求,然後返回bool值,對應是否修改文本
書中原本的要求是限制TextField中只能輸入一個小數點,已經給出了相關實現
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let existingTextHasDecimalSeparator = textField.text?.range(of: ".")
let replacementTextHasDecimalSepatator = string.range(of: ".")
if existingTextHasDecimalSeparator != nil, replacementTextHasDecimalSepatator != nil {
return false
} else {
return true
}
}
實現很簡單,無非就是利用了Swift中string的range方法,對已輸入的字符串和待輸入的字符串中的小數點進行查找
解決問題
後面留了一個課後題:要求使用CharacterSet實現禁止字母的輸入,我這裏直接實現了只能輸入數字和小數點的限制
首先初始化一個只含小數點和數字的CharacterSet
let characterSet = CharacterSet.init(charactersIn: ".0123456789")
然後同樣是在replacementString中對characterSet中的字符進行查找,如果結果不為nil就返回false
if string.rangeOfCharacter(from: characterSet) == nil {
return false
}
把這些全部寫到前面的textField函數中,編譯運行會發現一個問題——刪除鍵失效了
重新認真看doc,會發現實際上在按下刪除鍵的時候textField函數也被調用了
但是replacementString會是一個空字符串,而前面沒有考慮這個問題,就會導致刪除鍵失效
修改之後如下
if string.rangeOfCharacter(from: characterSet) == nil,
!string.isEmpty {
return false
}