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

Posted

技术标签:

【中文标题】使用 `textField:shouldChangeCharactersInRange:`,如何获取包含当前键入字符的文本?【英文标题】:Using `textField:shouldChangeCharactersInRange:`, how do I get the text including the current typed character? 【发布时间】:2010-02-04 07:44:34 【问题描述】:

我正在使用下面的代码尝试更新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”时

我做错了什么?

【问题讨论】:

提醒一下,始终使用 "Editing Changed" 事件要容易得多。.. 只需将它在 IB 中拖到您创建的函数中即可。 请注意,编辑更改事件不会捕获任何以编程方式生成的文本更改事件,例如自动更正/自动完成/文本替换。 【参考方案1】:

-shouldChangeCharactersInRange 被调用 before 文本字段实际更改其文本,这就是您获得旧文本值的原因。更新使用后获取文本:

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

【讨论】:

几乎对我有用。如果我输入一个字符,这有效。如果我按下删除按钮,它会删除两个字符。对我来说,以下建议有效:***.com/questions/388237/… 基本上,将 UITextField 中的'n'drop 拖放到您的代码中(以创建一个函数),然后右键单击您的 TextField,然后从圆圈中拖放“编辑已更改”为您的新功能。 (叹气。我有时会想念 Visual Studio..) 我也觉得这是一个有效的答案,但不是答案。 @tomute 回答了实现您想要的最佳方法 或 Swift 中的 textFiel.text = (textFiel.text as NSString).stringByReplacingCharactersInRange(range, withString: string) @MikeGledhill 您可以以编程方式执行相同的操作:[textField addTarget:self action:@selector(textFieldEditingChanged:) forControlEvents:UIControlEventEditingChanged]【参考方案2】:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

    NSString * searchStr = [textField.text stringByReplacingCharactersInRange:range withString:string];

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

【讨论】:

【参考方案3】:

斯威夫特 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_s 我直接从我的 Xcode 项目中复制了这个 sn-p,它工作正常。您是否使用 Xcode 8.1 和 ios 10.1 目标?【参考方案4】:

不要使用 UITextFieldDelegate,而是尝试使用 UITextField 的"Editing Changed" 事件。

【讨论】:

【参考方案5】:

在 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

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

这是你需要的代码,

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

【讨论】:

【参考方案8】:

使用保护

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
    

【讨论】:

【参考方案9】:

我的解决方案是使用UITextFieldTextDidChangeNotification

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

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

【讨论】:

【参考方案10】:

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

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

【讨论】:

以上是关于使用 `textField:shouldChangeCharactersInRange:`,如何获取包含当前键入字符的文本?的主要内容,如果未能解决你的问题,请参考以下文章

第一篇 用于测试使用

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份