从 unicode 字符符号获取范围。 Swift
Get range from unicode character symbols. Swift
我用textView(_: shouldChangeTextIn: replacementText:)
函数根据情况改变输入数据。我使用范围,但在使用 unicode 字符符号时无法获得 Swift 范围(例如 ( ͡° ͜ʖ ͡°) )。请告诉我怎么做?
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
let maxLenthNotReached = textView.text.count + (text.count - range.length) <= maxTextLength
if maxLenthNotReached {
guard let newRange = Range(range, in: identityString) else { return false }
identityString = identityString.replacingCharacters(in: newRange, with: text)
}
return maxLenthNotReached
}
应用崩溃示例http://take.ms/ojIJq
更新: 我改了这个方法但是删除的时候又崩溃了
"entering data" ""
"testString" "༼ つ ͡° ͜ʖ ͡° ༽つ( ͡° ͜ʖ ͡"
"entering data" ""
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
debugPrint("textView.text", textView.text)
testString = textView.text.replacingCharacters(in: Range(range, in: textView.text)!, with: text)//
debugPrint("testString", testString)
return true
}
更新 1: 我在 textView 中输入了这些字符
( ͡° ͜ʖ ͡°)༼ つ ͡° ͜ʖ ͡° ༽つ
然后我开始删除右边的三个符号后从右边到左边的字符° ༽つ
,汽车表情符号已经离开,所以我无法获取范围,因为我把守卫和应用程序不会崩溃,如果我删除它当然会有应用程序崩溃。
完整代码
class ViewController: UIViewController {
// MARK: - IBOutlets
@IBOutlet private weak var textView: UITextView! {
didSet {
textView.delegate = self
textView.text = "( ͡° ͜ʖ ͡°)༼ つ ͡° ͜ʖ ͡° ༽つ"
}
}
// MARK: - Properties
private var testString = ""
}
extension ViewController: UITextViewDelegate {
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
guard let newRange = Range(range, in: textView.text) else {
return false
}
testString = textView.text.replacingCharacters(in: newRange, with: text)
return true
}
}
更新 2:在与 Martin 交谈后,我发现并提供了一个细节,这个问题只发生在 Google 键盘上,并且使用默认键盘一切正常不出所料。
我的原始行是 "( ͡° ͜ʖ ͡°)༼ つ ͡° ͜ʖ ͡° ༽つ”
,这行用于 example.If 我开始从左到右删除这一行,我的应用程序崩溃了,Martin 要求显示最新的应用程序崩溃前控制台中的数据,崩溃前最后打印的是 textView" "( ͡° ͜ʖ ͡°)༼ つ ͡° ͜ʖ ͡" "range" {27, 1}
讨论结果:
- OP 正在使用 Google 键盘,
调用文本视图委托方法
textView.text = "( ͡° ͜ʖ ͡°)༼ つ ͡° ͜ʖ ͡"
range = { 27, 1 }
然后
let newRange = Range(range, in: textView.text)
returns nil
.
原因是范围指向</code>字符的“中间”,
它存储为 UTF-16 代理对。这是一个简化的自包含
示例:</p>
<pre><code>let text = "Hello !"
let range = NSRange(location: 7, length: 1)
let newRange = Range(range, in: text)
print(newRange as Any) // nil
对我来说,这看起来像是一个错误(在 Google 键盘上?),但有一个可能的解决方法。
“技巧”是确定“组合”的最近周围范围
字符序列”,这是如何做到的
(比较 ):
extension String {
func safeRange(from nsRange: NSRange) -> Range<String.Index>? {
guard nsRange.location >= 0 && nsRange.location <= utf16.count else { return nil }
guard nsRange.length >= 0 && nsRange.location + nsRange.length <= utf16.count else { return nil }
let from = String.Index(encodedOffset: nsRange.location)
let to = String.Index(encodedOffset: nsRange.location + nsRange.length)
return rangeOfComposedCharacterSequences(for: from..<to)
}
}
现在
let newRange = textView.text.safeRange(from: range)
returns 包含整个 </code> 字符的 <code>String
范围。在我们的
简化示例:
let text = "Hello !"
let range = NSRange(location: 7, length: 1)
let newRange = text.safeRange(from: range)
print(newRange as Any) // Optional(Range(...))
print(text.replacingCharacters(in: newRange!, with: "")) // Hello !
我用textView(_: shouldChangeTextIn: replacementText:)
函数根据情况改变输入数据。我使用范围,但在使用 unicode 字符符号时无法获得 Swift 范围(例如 ( ͡° ͜ʖ ͡°) )。请告诉我怎么做?
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
let maxLenthNotReached = textView.text.count + (text.count - range.length) <= maxTextLength
if maxLenthNotReached {
guard let newRange = Range(range, in: identityString) else { return false }
identityString = identityString.replacingCharacters(in: newRange, with: text)
}
return maxLenthNotReached
}
应用崩溃示例http://take.ms/ojIJq
更新: 我改了这个方法但是删除的时候又崩溃了
"entering data" ""
"testString" "༼ つ ͡° ͜ʖ ͡° ༽つ( ͡° ͜ʖ ͡"
"entering data" ""
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
debugPrint("textView.text", textView.text)
testString = textView.text.replacingCharacters(in: Range(range, in: textView.text)!, with: text)//
debugPrint("testString", testString)
return true
}
更新 1: 我在 textView 中输入了这些字符
( ͡° ͜ʖ ͡°)༼ つ ͡° ͜ʖ ͡° ༽つ
然后我开始删除右边的三个符号后从右边到左边的字符° ༽つ
,汽车表情符号已经离开,所以我无法获取范围,因为我把守卫和应用程序不会崩溃,如果我删除它当然会有应用程序崩溃。
完整代码
class ViewController: UIViewController {
// MARK: - IBOutlets
@IBOutlet private weak var textView: UITextView! {
didSet {
textView.delegate = self
textView.text = "( ͡° ͜ʖ ͡°)༼ つ ͡° ͜ʖ ͡° ༽つ"
}
}
// MARK: - Properties
private var testString = ""
}
extension ViewController: UITextViewDelegate {
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
guard let newRange = Range(range, in: textView.text) else {
return false
}
testString = textView.text.replacingCharacters(in: newRange, with: text)
return true
}
}
更新 2:在与 Martin 交谈后,我发现并提供了一个细节,这个问题只发生在 Google 键盘上,并且使用默认键盘一切正常不出所料。
我的原始行是 "( ͡° ͜ʖ ͡°)༼ つ ͡° ͜ʖ ͡° ༽つ”
,这行用于 example.If 我开始从左到右删除这一行,我的应用程序崩溃了,Martin 要求显示最新的应用程序崩溃前控制台中的数据,崩溃前最后打印的是 textView" "( ͡° ͜ʖ ͡°)༼ つ ͡° ͜ʖ ͡" "range" {27, 1}
讨论结果:
- OP 正在使用 Google 键盘,
调用文本视图委托方法
textView.text = "( ͡° ͜ʖ ͡°)༼ つ ͡° ͜ʖ ͡" range = { 27, 1 }
然后
let newRange = Range(range, in: textView.text)
returns
nil
.
原因是范围指向</code>字符的“中间”,
它存储为 UTF-16 代理对。这是一个简化的自包含
示例:</p>
<pre><code>let text = "Hello !"
let range = NSRange(location: 7, length: 1)
let newRange = Range(range, in: text)
print(newRange as Any) // nil
对我来说,这看起来像是一个错误(在 Google 键盘上?),但有一个可能的解决方法。
“技巧”是确定“组合”的最近周围范围
字符序列”,这是如何做到的
(比较
extension String {
func safeRange(from nsRange: NSRange) -> Range<String.Index>? {
guard nsRange.location >= 0 && nsRange.location <= utf16.count else { return nil }
guard nsRange.length >= 0 && nsRange.location + nsRange.length <= utf16.count else { return nil }
let from = String.Index(encodedOffset: nsRange.location)
let to = String.Index(encodedOffset: nsRange.location + nsRange.length)
return rangeOfComposedCharacterSequences(for: from..<to)
}
}
现在
let newRange = textView.text.safeRange(from: range)
returns 包含整个 </code> 字符的 <code>String
范围。在我们的
简化示例:
let text = "Hello !"
let range = NSRange(location: 7, length: 1)
let newRange = text.safeRange(from: range)
print(newRange as Any) // Optional(Range(...))
print(text.replacingCharacters(in: newRange!, with: "")) // Hello !