需求:
如圖:
驗證碼輸入Demo.gif
思路:
視圖層級:
最底層一個隱藏的UITextView亚享,上面鋪的Label
輸入焦點在UITextView海洼,監(jiān)聽UITextView的輸入淹接,給Label賦值
通過Label顯示輸入的文字使用CAShapeLayer繪制光標
通過光標的顯示隱藏來控制光標的移動
基礎動畫控制光標閃動
坑點:
- 用戶有可能不按順序輸入鲸鹦。如:
1234憋沿,此時輸入光標移動到location=0來輸入
- 用戶有可能不按順序刪除汞扎。如:(支付寶注冊就有此bug)
1234季稳,此時輸入光標移動到location=1來刪除
- 從粘貼板粘貼進來不合法的驗證碼。
- 4澈魄、光標在退后臺后景鼠,返回前臺,光標動畫不動了
代碼實現與解決方案:
一痹扇、坑點1铛漓、2、3解決方案:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
// 輸入框已有的值
var inputText = textView.text ?? ""
if text.count == 0 { // 刪除
if range.location != inputText.count - 1 { // 刪除的不是最后一個
if inputText.count > 0 {
// 手動刪除最后一位
textView.text.removeLast()
textViewDidChange(textView)
}
return false
}
}
if let tempRange = Range.init(range, in: inputText) {
// 拼接輸入后的值
inputText = inputText.replacingCharacters(in: tempRange , with: text)
let isMeet = inputText.inputValuesMeetRule(integerCount: nil, decimalCount: 0)
if isMeet == false {
return isMeet
}
}
if inputText.count > inputTextNum {
return false
}
return true
}
二鲫构、坑點4解決方案:
NotificationCenter.default.addObserver(self, selector: #selector(becomeActive), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(enterBack), name: NSNotification.Name.UIApplicationDidEnterBackground, object: nil)
/// 去后臺
@objc fileprivate func enterBack() {
// 移除動畫
cursor.removeAnimation(forKey: "kOpacityAnimation")
}
/// 回前臺
@objc fileprivate func becomeActive() {
// 重新添加動畫
cursor.add(opacityAnimation, forKey: "kOpacityAnimation")
}