【iOS】只允许中英文数字输入,字符限制【整理】

  • 2020 年 3 月 28 日
  • 筆記

描述

在项目中遇到一个这样的需求

1、只允许用户输入中英文数字 2、最多只能输入6个中文 3、最多只能输入12个英文或数字 4、中英混排总长度不超过12(中文长度2,英文或数字长度1)

解决

搜了一下网上的解决方法,找到了两篇关于这个的方法,因此记录下来,方便日后直接使用。为了方便,都写成了extension方便调用

https://www.jianshu.com/p/0e4c32638c37 https://www.jianshu.com/p/4c621f509432

代码

1、String扩展

extension String {     /// 或者字符串的字节长度  中文-2,英文1     func getStringLengthOfBytes() -> Int {         var length = 0         for i in 0..<self.count {             let subStr = (self as NSString).substring(with:  NSMakeRange(i, 1))             if subStr.validateChinese() {                 length += 2             }else {                 length += 1             }         }         return length     }       /// 根据索引获取子字符串,长度以字节长度(中文-2,英文1)计算     func subBytesOfStringTo(index: Int) -> String {         var length = 0         var chineseNum = 0         var zifuNum = 0           for i in 0..<self.count {             let subStr = (self as NSString).substring(with:  NSMakeRange(i, 1))             if subStr.validateChinese() {                 if length + 2 > index {                     return self.subStringTo(chineseNum + zifuNum)                 }                 length += 2                 chineseNum += 1             }else {                 if length + 1 > index {                     return self.subStringTo(chineseNum + zifuNum)                 }                 length += 1                 zifuNum += 1             }         }         return self.subStringTo(index)     }       /// 检测中文     func validateChinese() -> Bool {         let pattern = "[\u4e00-\u9fa5]"         return self.isMatchRegularExp(pattern)     }       /// 是否匹配正则     func isMatchRegularExp(_ pattern: String) -> Bool {         guard let reg = try? NSRegularExpression(pattern: pattern, options: NSRegularExpression.Options.caseInsensitive) else {             return false         }         let result = reg.matches(in: self, options: .reportProgress, range: NSMakeRange(0, self.length))         return (result.count > 0)     }    }

2、监听textField的输入

使用UIControlEvents的editingChanged进行监听。其中需要特别处理的就是中文的输入,例如输入“黄河之水天上来”,在输入框显示“huanghezhishuitianshanglai”的时候,就会限制输入了,因此通过textField.markedTextRange判断是否有选中框存在(中文输入时,有选中框)

@objc fileprivate func textChange(textField: UITextField) {          let maxLength = 12          let text = textField.text ?? ""          guard let mode = textField.textInputMode?.primaryLanguage else {              return          }          // 简体中文输入,包括简体拼音,健体五笔,简体手写          if mode == "zh-Hans" {              if let selectedRange = textField.markedTextRange {                  //获取高亮部分                  if textField.position(from: selectedRange.start, offset: 0) == nil {                      if text.getStringLengthOfBytes() > maxLength {                          textField.text = text.subBytesOfStringTo(index: maxLength)                      }                  }              }else {                  if text.getStringLengthOfBytes() > maxLength {                      textField.text = text.subBytesOfStringTo(index: maxLength)                  }              }          }else {              if text.getStringLengthOfBytes() > maxLength {                  textField.text = text.subBytesOfStringTo(index: maxLength)              }          }      }

3、只允许输入中英文,数字

通过UITextField的代理shouldChangeCharactersIn,进行判断

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {          let pattern = "[a-zA-Z\u4E00-\u9FA5\u0030-\u0039]"          return string.isMatchRegularExp(pattern) || string.isEmpty      }