如何获取字符串指定NSRange对应的UTF8编码字节数?
如何根据NSRange获取字符串范围内的UTF8编码字节数?
要计算Swift字符串中NSRange对应范围的UTF8编码字节数,核心是把基于NSString字符索引的NSRange转换成Swift String的Range<String.Index>,再截取子串计算字节数,具体实现如下:
let str = "it's 🌮 time" let nsRange = NSRange(location: 5, length: 2) // 对应"🌮 "的范围 // 将Swift String转为NSString,用于NSRange转换 let nsStr = str as NSString guard let swiftRange = Range(nsRange, in: str) else { // 处理NSRange超出字符串范围的异常情况 print("无效的NSRange") return } // 截取对应子串并计算UTF8字节数 let subStr = str[swiftRange] let utf8ByteCount = subStr.utf8.count print(utf8ByteCount) // 输出4,因为🌮占3字节,空格占1字节
修复UITextView的字节限制逻辑
你当前的代理方法错误在于没有扣除被替换文本范围的UTF8字节数,导致粘贴替换时计算错误。修正后的代码如下:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { // 字符限制逻辑保持不变 if let charLimit = characterLimit { let currentChars = textView.text.count let newChars = text.count - range.length let totalChars = currentChars + newChars return totalChars <= charLimit } if let byteLimit = utf8EncodedByteLimit { let currentText = textView.text let nsText = currentText as NSString // 计算被替换范围的UTF8字节数 let bytesToRemove: Int if let swiftRange = Range(range, in: currentText) { bytesToRemove = currentText[swiftRange].utf8.count } else { bytesToRemove = 0 } // 计算新文本的UTF8字节数 let bytesToAdd = text.utf8.count // 计算修改后的总字节数 let newTotalBytes = currentText.utf8.count - bytesToRemove + bytesToAdd return newTotalBytes <= byteLimit } // 无限制时默认允许文本修改 return true }
关键说明
- NSRange转Swift Range:由于Swift String的字符索引是基于Unicode标量,而NSRange是基于NSString的UTF-16代码单元索引,必须通过
Range(_:in:)方法完成转换,避免索引不匹配导致的崩溃或错误计算。 - 字节数计算逻辑:修改后的总字节数 = 当前文本总字节数 - 被替换范围的字节数 + 新文本的字节数,这才是正确的替换场景下的字节数计算方式。
- 容错处理:增加了NSRange无效时的默认处理,避免因异常范围导致的逻辑错误。
内容的提问来源于stack exchange,提问作者lurning too koad
相关产品推荐
相关产品推荐

