1、輸入相關的優化問題
react
在大部分應用中,都有輸入的需求,面對衆多用戶,他們的想法各異,輸入的文本內容也是千奇百怪,面對不一樣的輸入,咱們該如何優化輸入體驗?這裏集中彙總輸入相關問題,主要以下:git
一、輸入控件UITextField跟隨鍵盤移動github
二、過濾輸入內容編程
三、響應編程的處理,去除體驗很差的對話框、HUD提示swift
四、中文輸入框架
2、輸入框隨鍵盤移動ide
界面構建有兩種方法,代碼或者storyboard/xib,這兩種方法在處理鍵盤移動上方法相同,這裏推薦使用已經封裝好的第三方框架:TPKeyboardAvoiding優化
一、代碼處理方法spa
rootView使用TPKeyboardAvoiding框架中的TPKeyboardAvoidingScrollView來初使化。例如,登陸界面,LoginViewController(繼承自UIViewController),處理方法以下:設計
let rootView = TPKeyboardAvoidingScrollView(frame: self.view.bounds); //... //add all subviews to rootView //... self.view.addSubview(rootView)
代碼構建界面,實現輸入框隨鍵盤移動,須要將類TPKeyboardAvoidingScrollView作爲根視圖來處理。
二、storyboard/xib處理辦法
storyboard/xib處理起來更簡單,將視圖控制器的rootView設置爲TPKeyboardAvoidingScrollView便可
(1)選擇控制器的根視圖
(2)設置默認實例化類
3、經常使用基本設置
一、經常使用基本設置
包括打開鍵盤、關閉鍵盤、指定鍵盤的輸入類型、指定return按鈕的類型,如如下代碼
//打開鍵盤 self.inputText.becomeFirstResponder() //關閉鍵盤 self.inputText.resignFirstResponder() //指定鍵盤的輸入類型 self.inputText.keyboardType = UIKeyboardType.NumberPad //指定return按鍵的類型 self.inputText.returnKeyType = UIReturnKeyType.Go
二、經過代理過濾輸入
經過UITextField/UITextView的代理,能夠更精確的控制輸入,例如:過濾指定字符、超過字符數禁止輸入等
(1)UITextField代碼以下:
//設置代理,可根據實際狀況來設置代理,這裏使用self來指定 self.textField.delegate = self //代理方法實現 func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { //禁止輸入空格 if (string == " ") { return false } //按下回車後取消鍵盤 if (string == "\n") { textField.resignFirstResponder() return false } return true }
(2)UITextView代碼以下:
/設置代理,可根據實際狀況來設置代理,這裏使用self來指定 self.textView.delegate = self //代理方法實現 func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { //禁止輸入空格 if (text == " ") { return false } //按下回車後取消鍵盤 if (text == "\n") { textView.resignFirstResponder() return false } return true }
UITextField/UITextView能夠經過代理方法實時檢測用戶輸入的內容,方便對輸入約束,例如,在輸入超過10個字符時,禁止用戶輸入,不過這種體驗很差,建議不要使用
4、響應編程處理,精確提示信息
一、如何優化
輸入信息的約束通常是將規則直接提示給用戶,例如:社交中用戶暱稱的輸入:
請輸入1-8位的字符做爲暱稱,不能包括空格、回車、標點
用戶點擊肯定按鈕以後,檢查輸入的合法性,並經過對話框(或HUD)的形式,提示給用戶信息
上面的處理方式,十分常見,能知足基本需求。不過咱們已經再也不採用上面的設計,緣由有如下兩點:
1.提示信息過多,大部分用戶不會看
2.對話框及HUD提示比較突兀,容易使用戶產生挫敗感
在實際開發過程當中,精減提示信息爲
請輸入1-8個字符
用戶主動輸入空格、回車、標點這些字符或者超出長度時,才主動提示給用戶信息,以下圖,無輸入,肯定按鈕disable,只提示極少有用信息
輸入合法,肯定按鈕enable
輸入不合法,高亮錯誤顯示,肯定按鈕disable
二、代碼實現
使用第三方框架ReactiveCocoa,首先實如今用戶輸入時,下方提示及右側圖片的功能(不使用三方框架,可本身經過代理實現)
@IBOutlet weak var nickTextField: UITextField!//文本輸入框 @IBOutlet weak var checkResultShowImageView: UIImageView!//輸入框右側圖片 @IBOutlet weak var button: UIButton! @IBOutlet weak var hintLabel: UILabel!//文本框下方提示文字 override func viewDidLoad() { super.viewDidLoad() //配置輸入 configInput() } func configInput() { self.nickTextField.rac_textSignal().subscribeNext { (text) -> Void in if (text == nil || text.length == 0) { self.checkResultShowImageView.hidden = false return } self.checkResultShowImageView.hidden = true var imageName = "" if (self.checkInputValidate()) { imageName = "ok.png" self.hintLabel.text = "" } else { imageName = "warning.png" self.hintLabel.text = "超出\(text.length - 8)個字符" } self.checkResultShowImageView.image = UIImage(named: imageName) } } func checkInputValidate() -> Bool { //輸入條件檢查,這裏示例,只檢查字符長度 let length = (self.nickTextField.text as NSString).length return length > 0 && length <= 8 }
下面實現功能:根據輸入的合法性,設置按鈕的enabled屬性,此步驟須要下載文件RAC語法支持文件,更詳細介紹Swift支持ReactiveCocoa
func configButtonEnable() { RAC(self.button, "enabled") <~ RACSignal.combineLatest( [self.nickTextField.rac_textSignal()], reduce: { () -> AnyObject! in return self.checkInputValidate() }) }
5、中文處理辦法
有中文輸入時,上面的字數檢查不許確,如經過輸入法輸入**"我愛中國文化"**6個字符時self.nickTextField.text的字符個數爲23個,提示信息不正確
UITextView/UITextFiled有一個markedTextRange屬性,用於標識當前是否有選中的文本(有選中文本時即爲上圖中的未完成輸入狀態),利用此原理來解決中文等相似問題
@IBOutlet weak var nickTextField: UITextField! @IBOutlet weak var checkResultShowImageView: UIImageView! @IBOutlet weak var button: UIButton! @IBOutlet weak var hintLabel: UILabel! var chineseText: NSString! override func viewDidLoad() { super.viewDidLoad() self.nickTextField.delegate = self filterInput() configButtonEnable() } func filterInput() { self.nickTextField.rac_textSignal().subscribeNext { (text) -> Void in if(self.nickTextField.markedTextRange != nil) { return; } //這裏能夠加入去除空格,標點等操做 self.chineseText = text as NSString if (text == nil || text.length == 0) { self.checkResultShowImageView.hidden = false return } self.checkResultShowImageView.hidden = true var imageName = "" if (self.checkInputValidate()) { imageName = "ok.png" self.hintLabel.text = "" } else { imageName = "warning.png" self.hintLabel.text = "超出\(text.length - 8)個字符" } self.checkResultShowImageView.image = UIImage(named: imageName) } } func checkInputValidate() -> Bool { //輸入條件檢查,這裏示例,只檢查字符長度 let length = chineseText.length return length > 0 && length <= 8 } func configButtonEnable() { RAC(self.button, "enabled") <~ RACSignal.combineLatest( [self.nickTextField.rac_textSignal()], reduce: { () -> AnyObject! in if(self.nickTextField.markedTextRange == nil) { return self.checkInputValidate() } return self.button.enabled }) } @IBAction func buttonPressed(sender: AnyObject) { println("------>\(self.chineseText)") }
6、總結
輸入是手機App中最耗時的操做,處理不當很容易失去用戶,這裏總結如下幾點
1.不要將全部的約束信息直接展現給用戶,只展現那些對大部分用戶都有用的信息,對於其餘約束
在用戶輸入錯誤的時候再提示
2.儘可能少用或者不用對話框及HUD的方式提示錯誤
3.提示信息準確,例如超出字符數,一種提示爲:超出最大140字符
另外一種爲:超出n個字符,顯而後者提示對用戶更有價值
4.不要擅自更改用戶輸入內容或者粗暴禁止用戶輸入