【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 }