iOS8的预测输入多次调用UITextView
的以下委托方法,导致所选单词多次插入到视图中。
此代码适用于键入单个字母和复制/粘贴,但不适用于使用预测输入栏时;为什么不呢?
- (BOOL) textView:(UITextView*)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString*)text
{
textView.text = [textView.text stringByReplacingCharactersInRange:range withString:text];
return false;
}
使用此代码;如果我输入一个空的UITextView并点击""在预测文本(自动完成)视图中,它插入" The"通过对此方法进行三次调用进入视图。传递给每个调用的参数是:
{0,0}
文字:@"The"
{0,0}
文字:@"The"
{3,0}
文字:@" "
我能理解的空间;但为什么插入""两次?
答案 0 :(得分:16)
我遇到了同样的问题。看来,使用预测文本,在该委托方法中设置textView.text会再次触发对该委托方法的立即调用(据我所知,这只发生在预测文本中)。
我通过用一个警卫围绕我的textView更改来修复它:
private var hack_shouldIgnorePredictiveInput = false
func textView(textView: UITextView!, shouldChangeTextInRange range: NSRange, replacementText text: String!) -> Bool {
if hack_shouldIgnorePredictiveInput {
hack_shouldIgnorePredictiveInput = false
return false
}
hack_shouldIgnorePredictiveInput = true
textView.text = "" // Modify text however you need. This will cause shouldChangeTextInRange to be called again, but it will be ignored thanks to hack_shouldIgnorePredictiveInput
hack_shouldIgnorePredictiveInput = false
return false
}
答案 1 :(得分:1)
不是答案,而是更安全的解决方法:
class TextViewTextChangeChecker {
private var timestamp: TimeInterval = 0
private var lastRange: NSRange = NSRange(location: -1, length: 0)
private var lastText: String = ""
func shouldChange(text:String,in range: NSRange) -> Bool {
let SOME_SHORT_TIME = 0.1
let newStamp = Date().timeIntervalSince1970
let same = lastText == text && range == lastRange && newStamp - timestamp < SOME_SHORT_TIME
timestamp = newStamp
lastRange = range
lastText = text
return !same
}
}
这仍然没有帮助我,因为从shouldChangeTextInRange
函数更改textView会将autocapitalizationType
更改为.word
(仅是通过行为,而不是字段本身)。
答案 2 :(得分:0)
我修改了理查德维纳布尔接受的答案,因为正如JLust在评论中指出的那样,第三次与空间的通话让我失望。
我添加了
private var predictiveTextWatcher = 0
并且
if predictiveTextWatcher == 1 {
predictiveTextWatcher = 0
return false
}
if hack_shouldIgnorePredictiveInput {
predictiveTextWatcher += 1
hack_shouldIgnorePredictiveInput = false
return false
}
这一切都很漂亮,但总比没有好。
最佳,