在我们使用UITextView的过程中,经常会遇到增加提示文本和限制字数的需求,特别是限制字数时输入拼音的情况,今天特意研究了下,封装了一个工具类,先上图:
实现过程主要是监听以下两个方法,第一个用于限制输入,第二个用于计算剩余字数:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
//该方法会在键盘输入时触发,返回false时输入无效
}
func textViewDidChange(_ textView: UITextView) {
//该方法会有textView.text值通过输入操作(非代码)变化时触发
}
先来看限制输入方法具体实现:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
//拼接不限制输入,textview将会得到的值
let jointStr = (textView.text as NSString).replacingCharacters(in: range, with: text)
//得到剩余字数
let remainNumber = maxNumber - jointStr.length()
//当没有候选字符,且字数超过限制时,输入无效
if self.markedTextRange == nil && remainNumber < 0 {
return false
}else {
return true
}
}
计算剩余字数方法:
func textViewDidChange(_ textView: UITextView) {
//判断提示文本是否显示
if textView.text.length() == 0 {
self.placeholderLabel.isHidden = false
}else {
self.placeholderLabel.isHidden = true
}
//没有候选字符,拼音输入中
if self.markedTextRange == nil {
let text = textView.text as NSString
if (text.length > self.maxNumber) {
// 记录光标位置
let selectRange = textView.selectedRange
// 防止最后一位是emoji表情
let rangeIndex = text.rangeOfComposedCharacterSequence(at: self.maxNumber)
if rangeIndex.length == 1 {
textView.text = text.substring(to: self.maxNumber)
}else {
if self.maxNumber == 1 {
textView.text = ""
}else {
textView.text = text.substring(to: self.maxNumber-1)
}
}
// 重新设置光标位置
if selectRange.location > textView.text.length() {
textView.selectedRange = NSRange.init(location: textView.text.length(), length: 0)
}else {
textView.selectedRange = selectRange
}
}
}
}
基本流程就上面这些,需要注意:
1.拼音输入中判断self.markedTextRange;
2.记录光标输入位置,防止光标跑到末尾;
代码已上传至我的github ,有需要的可以去下载看下。