在开发时,我们经常遇到限制一个字符串的长度,有时候会要求不超过N个字符,简单封装了下。
1. 计算字符串的字符数
extension String {
/// 字符数
var charactersCount: Int {
guard !isEmpty else { return 0 }
var bytesCount = count
let array = Array(self)
for i in 0..<count {
let charValue = array[i]
if let asciiValue = charValue.utf8.first {
if asciiValue < 0 || asciiValue > 127 {
bytesCount += 1
}
}
}
return bytesCount
}
}
2. 截取前N个字符
extension String {
/// 获取前maxCharacterCount个字符对应的字符串
/// - Parameter maxCharacterCount: 最大字符数
/// - Returns: 截取的字符串
func prefixText(with maxCharacterCount: Int) -> Self {
guard !isEmpty else { return "" }
var maxLength = maxCharacterCount
var subLength = 0
let array = Array(self)
for i in 0..<count {
let charValue = array[i]
maxLength -= 1
if let asciiValue = charValue.utf8.first {
if asciiValue < 0 || asciiValue > 127 {
maxLength -= 1
}
}
if maxLength < 0 {
break
} else {
subLength += 1
}
}
return Self(prefix(subLength))
}
}
3. 监听UITextField内容变化,若字符数超出N个,则截取前N个字符数
extension ViewController: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
guard let text = textView.text.qjn_stringByTrim() else {
// do something
return
}
if let selectedRange = textView.markedTextRange, let pos = textView.position(from: selectedRange.start, offset: 0) {
return
}
DispatchQueue.global().async {
if text.charactersCount > N {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
textView.text = text.prefixText(with: N)
// do something
}
} else {
// do something
}
}
}
}