我发现函数String.characters.count对于行是表情符号标记的行有一个奇怪的行为:
import UIKit
var flag = ""
print(flag.characters.count)
print(flag.unicodeScalars.count)
print(flag.utf16.count)
print(flag.utf8.count)
flag = "000"
print(flag.characters.count)
print(flag.unicodeScalars.count)
print(flag.utf16.count)
print(flag.utf8.count)
我想在UITextView中编写和编辑时限制文本的字符串长度。 其实我的代码是这样的:
var lastRange: NSRange? = nil
var lastText: String? = nil
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText string: String) -> Bool {
if string == "\n" {
// Execute same code
return false
}
var text = string.uppercaseString
if lastText != text || lastRange != nil && (lastRange!.location != range.location || lastRange!.length != range.length) {
lastRange = range
lastText = text
var text = (self.textView.text ?? "" as NSString).stringByReplacingCharactersInRange(range, withString: string)
// Delete chars if length more kMaxLengthText
while text.utf16.count >= kMaxLengthText {
text.removeAtIndex(text.endIndex.advancedBy(-1))
}
// Set position after insert text
self.textView.selectedRange = NSRange(location: range.location + lastText!.utf16.count, length: 0)
}
return false
}
答案 0 :(得分:5)
更新Swift 4(Xcode 9)
从Swift 4(使用Xcode 9 beta测试)标志(即成对的区域标志)开始 指标)被视为单个字素集群,按照规定 Unicode 9标准。所以计数标志并删除最后一个 字符(不管它是否是旗帜)现在简单如下:
var flags = ""
print(flags.count) // 6
flags.removeLast()
print(flags.count) // 5
print(flags) //
(Swift 3及更早版本的旧答案:)
没有错误。一系列“区域指标”字符是 单个“扩展字形集群”,这就是为什么
var flag = ""
print(flag.characters.count)
打印1
(比较Swift countElements() return incorrect value when count flag emoji)。
另一方面,上面的字符串由12个Unicode标量组成 (是+),每个都需要两个UTF-16代码点。
要将字符串分成必须的“可见实体” 考虑“组合字符序列”,比较How to know if two emojis will be displayed as one emoji?。
我没有一个优雅的解决方案(也许有人有更好的解决方案)。 但是一种选择是将字符串分成数组 组合字符,必要时从数组中删除元素, 然后再次组合字符串。
示例:
extension String {
func composedCharacters() -> [String] {
var result: [String] = []
enumerateSubstringsInRange(characters.indices, options: .ByComposedCharacterSequences) {
(subString, _, _, _) in
if let s = subString { result.append(s) }
}
return result
}
}
var flags = ""
var chars = flags.composedCharacters()
print(chars.count) // 6
chars.removeLast()
flags = chars.joinWithSeparator("")
print(flags) //
答案 1 :(得分:0)
@ Martin对swift3的回答,有一些修改
注意:我已将扩展名转换为函数
func composedCharacters(str:String) -> [String] {
var result: [String] = []
str.enumerateSubstrings(in: str.startIndex..<str.endIndex,options: .byComposedCharacterSequences) {
(subString, _, _, _) in
if let s = subString { result.append(s) }
}
return result
}
var flags = ""
var chars = composedCharacters(str:flags)
print(chars.count) // 6
chars.removeLast()
flags = chars.joined(separator:"")
print(flags) //