使用‘ textField: should dChangeChartersInRange:’,如何获得包含当前输入字符的文本?

我正在使用下面的代码,尝试让 textField2的文本内容得到更新,以匹配 textField1的每当用户键入在 textField1

- (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange: (NSRange)range replacementString: (NSString *)string {
if (theTextField == textField1){
[textField2 setText:[textField1 text]];
}
}

然而,我观察到的结果是..。

TextField2是“12”,而 textField1是“123”

TextField2是“123”,而 textField1是“1234”

当我想要的是:

TextField2是“123”,而 textField1是“123”

TextField2是“1234”,而 textField1是“1234”

我做错了什么?

95756 次浏览

-shouldChangeCharactersInRange被称为 之前文本字段实际上改变了它的文本,这就是为什么你会得到旧的文本值。更新后获取文本使用:

[textField2 setText:[textField1.text stringByReplacingCharactersInRange:range withString:string]];

尝试使用 UITextField 的 “编辑变了”事件,而不是使用 UITextFieldCommittee。

这是你需要的代码,

if ([textField isEqual:self.textField1])
textField2.text = [textField1.text stringByReplacingCharactersInRange:range withString:string];
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString * searchStr = [textField.text stringByReplacingCharactersInRange:range withString:string];


NSLog(@"%@",searchStr);
return YES;
}

我的解决方案是使用 UITextFieldTextDidChangeNotification

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(copyText:) name:UITextFieldTextDidChangeNotification object:nil];

不要忘记在 dealloc方法中调用 [[NSNotificationCenter defaultCenter] removeObserver:self];

快速版本:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {


if string == " " {
return false
}


let userEnteredString = textField.text


var newString = (userEnteredString! as NSString).stringByReplacingCharactersInRange(range, withString: string) as NSString


print(newString)


return true
}

使用防护罩

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
guard case let textFieldString as NSString = textField.text where
textFieldString.stringByReplacingCharactersInRange(range, withString: string).length <= maxLength else {
return false
}
return true
}

Swift 3

Based on the accepted answer, the following should work in Swift 3:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {


let newString = NSString(string: textField.text!).replacingCharacters(in: range, with: string)


return true
}

注意

StringNSString都有称为 replacingCharacters:inRange:withString的方法。然而,正如预期的那样,前者期望一个 Range实例,而后者期望一个 NSRange实例。textField委托方法使用 NSRange实例,因此在本例中使用了 NSString

如果您需要用这个替换文本字段文本,您可以使用我的解决方案(Swift 3) : https://gist.github.com/Blackjacx/2198d86442ec9b9b05c0801f4e392047

替换之后,您只需获取 textField.text来检索组合文本。

在 Swift (4)中,没有 NSString(纯 Swift) :

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {


if let textFieldString = textField.text, let swtRange = Range(range, in: textFieldString) {


let fullString = textFieldString.replacingCharacters(in: swtRange, with: string)


print("FullString: \(fullString)")
}


return true
}

作为延伸:

extension UITextField {


func fullTextWith(range: NSRange, replacementString: String) -> String? {


if let fullSearchString = self.text, let swtRange = Range(range, in: fullSearchString) {


return fullSearchString.replacingCharacters(in: swtRange, with: replacementString)
}


return nil
}
}


// Usage:


func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {


if let textFieldString = textField.fullTextWith(range: range, replacementString: string) {
print("FullString: \(textFieldString)")
}


return true
}