使用`textField:shouldChangeCharactersInRange:`,如何获取包含当前键入字符的文本?


116

我正在使用下面的代码尝试使用户输入的textField2内容更新为匹配。textField1textField1

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

但是,我观察到的输出是...

当textField1为“ 123”时,textField2为“ 12”

当textField1为“ 1234”时,textField2为“ 123”

...当我想要的是:

当textField1为“ 123”时,textField2为“ 123”

当textField1为“ 1234”时,textField2为“ 1234”

我究竟做错了什么?


8
提醒一下,始终使用“ Edited Changed”事件非常容易..只需将其拖动到IB中即可。
Fattie 2013年

请注意,编辑更改事件不会捕获以编程方式生成的任何文本更改事件,例如,自动更正/自动完成/文本替换。
shim

Answers:


272

-shouldChangeCharactersInRange文本字段实际更改其文本之前被调用,这就是为什么您获得旧文本值的原因。要在更新后获取文本,请使用:

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

15
几乎对我有用。如果我键入一个字符,则可以。如果按删除按钮,它将删除两个字符。对我来说,以下建议有效:stackoverflow.com/questions/388237/… 基本上,将UITextField中的“拖放”到您的代码中(以创建一个函数),然后右键单击TextField,然后拖动“ n”从“修改后的内容”圈子中移至您的新功能。(叹气。有时我会想念Visual Studio。)
Mike Gledhill

我也觉得这是一个有效的答案,但不是答案。@tomute回答了完成您想要的事情的最佳方法
Pedro Borges

5
或textFiel.text =(textFiel.text作为的NSString).stringByReplacingCharactersInRange(范围,withString:字符串)在夫特
最大

@MikeGledhill您可以通过编程方式做同样的事情:[textField addTarget:self action:@selector(textFieldEditingChanged:) forControlEvents:UIControlEventEditingChanged]
史蒂夫·

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

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

40

迅捷3

根据公认的答案,以下应在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在这种情况下。


replacingCharacters应该是stringByReplacingCharactersInRange
Alan Scarpa

1
@Alan_s我直接从我的Xcode项目复制了此代码段,并且运行正常。您是否将Xcode 8.1与iOS 10.1结合使用?
focorner


13

在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
}

8

它的Swift版本:

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
}

5

这是您需要的代码,

if ([textField isEqual:self.textField1])
  textField2.text = [textField1.text stringByReplacingCharactersInRange:range withString:string];

1

使用警卫

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
    }

0

我的解决方案是使用UITextFieldTextDidChangeNotification

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

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.