【问题标题】:Detecting a change to text in UITextfield检测 UITextfield 中文本的更改
【发布时间】:2013-03-07 13:29:39
【问题描述】:

我希望能够检测UITextField 中的某些文本是否发生了更改,以便我可以启用UIButton 来保存更改。

【问题讨论】:

    标签: objective-c ipad ios6 uitextfield uitextfielddelegate


    【解决方案1】:

    与其观察通知或实现textField:shouldChangeCharacterInRange:replacementString:,不如添加一个事件目标更容易:

    [textField addTarget:self
                  action:@selector(myTextFieldDidChange:)
        forControlEvents:UIControlEventEditingChanged];
    
    - (void)myTextFieldDidChange:(id)sender {
        // Handle change.
    }
    

    请注意,事件是UIControlEventEditingChanged不是 UIControlEventValueChanged!

    与其他两个建议的解决方案相比的优点是:

    • 您无需记住使用 NSNotificationCenter 取消注册控制器。
    • 事件处理程序被调用,这意味着textField.text 包含用户实际输入的文本。 textField:shouldChangeCharacterInRange:replacementString: 委托方法在应用更改之前被调用,因此textField.text 尚未向您提供用户刚刚输入的文本 - 您必须先自己应用更改。

    【讨论】:

    • 如何在此方法“myTextFieldDidChange”中检测退格键按下事件。意味着您能否解释“您必须先自己应用更改”。部分答案?
    • @ViruMax:通知并不意味着检测单次按键。但是,如果您将文本字段的值保存在通知处理程序中更新的属性中,您可以在更新属性之前比较长度,从而知道字符是否已被删除、替换或添加。关于“您必须自己应用更改”:请参阅the answer that deals with the UITextFieldDelegate method(您需要调用stringByReplacingCharactersInRange:withString: 以获取更改的结果字符串)。
    • 此方法不适用于自动更正,当用户输入错误打印的文本然后再次点击同一文本字段时。不会调用此方法。 :[
    【解决方案2】:

    利用UITextFieldTextDidChange 通知或在文本字段上设置代理并注意textField:shouldChangeCharactersInRange:replacementString

    如果您想通过通知查看更改,您需要在代码中使用类似的内容来注册notification

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldDidChange:) name:UITextFieldTextDidChangeNotification object:theTextField];
    

    这里的TextField 是您要观看的UITextField 的实例。上面代码中self是实例的类必须实现textFieldDidChange,像这样:

    - (void)textFieldDidChange:(NSNotification *)notification {
        // Do whatever you like to respond to text changes here.
    }
    

    如果文本字段的寿命将超过observer,那么您必须注销观察者的dealloc 方法中的通知。实际上,即使文本字段的寿命不超过观察者,这样做也是一个好主意。

    - (void)dealloc {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
        // Other dealloc work
    }
    

    【讨论】:

    • 感谢您的帮助,但我在语法上苦苦挣扎。我认为它应该是这样的 - (void)UITextFieldTextDidChange:(UITextField *)textField { action to take } 但它似乎不起作用
    • 对于通知,您必须向 NSNotificationCenter 注册通知的观察者。查看 Apple 的 NSNotificationCenter 文档。这是 iOS 和 Mac OS X 应用程序开发中非常常见的模式。
    • 再次感谢。我想我明白了,但我应该把最初的 NSNotifcationCenter 线放在哪里?无论我放在哪里,它都会引发错误 - 使用未声明的“自我”标识符。此外,它如何知道我正在检查哪个 TextField 的更改?这个对象是:theTextView 吗?
    • 通常它会在观察者的 init 方法中(如果观察者是从 xib 文件加载的,则为 awakeFromNib,如果观察者是 UIViewController 的实例,则为 viewDidLoad)。如果不了解更多关于程序结构的信息,很难具体说明。您看到的错误表明您已将初始行放在任何实例方法之外。我鼓励您在此处研究链接到 Apple 文档的示例代码:developer.apple.com/library/mac/#documentation/Cocoa/Reference/…
    • 我查看了一些示例,现在将其放在 ViewDidLoad 中,没有任何错误。我已将对象更改为我的文本字段的名称并添加了其他(无效)方法。一切看起来都不错,但是当我运行它并更改此字段中的任何文本时,什么都没有发生。别担心——你给了我很大的帮助,我会继续努力的。谢谢。
    【解决方案3】:

    为此,首先您需要为您的文本字段分配委托引用。并且,最好应该是作为视图文件所有者的 vew 控制器。 就像

    myTextField.delegate = myViewControllerReferenceVariable
    

    并在您的 viewController 界面中,告诉您将通过

    实现 UITextFieldDelegate
    @interface MyViewController:UIViewController<UITextFieldDelegate>
    

    并且在您的视图控制器实现中覆盖

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    

    所以代码看起来像

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
         {
            text = [textfield.text stringByReplacingCharactersInRange:range withString:string];
            if (textfield == refToTextFieldYouWantToCheck) {
                if ( ! [textToCheck isEqualToString:text] ) {
                   [theButtonRef setEnabled:YES];
                } 
             }
               return YES; //If you don't your textfield won't get any text in it
          }
    

    您还可以订阅通知,恕我直言,这有点混乱 你可以找到如何做到这一点here

    【讨论】:

    • 再次感谢您的帮助,但这不只是查看是否输入了一些文本吗? (即长度现在> 0)文本字段中已有文本,我想检测它是否已更改。
    • @RichardGriffiths 对不起,我以为你想检查内容的存在,我现在已经更正了。您是否尝试放置占位符文本?
    • 这是正确的答案,不知道为什么它不被接受。每当输入或删除新字符时,都会触发此特定方法。如果您只想检查内容长度是否大于 0,请使用其他委托方法之一,例如 didBeginEditing 等
    • 不是解决此问题的正确方法,因为在对文本进行更改之前调用此方法。换句话说,如果您已经输入了fo,然后又输入了另一个o,那么textField.text 仍然是fo,而不是foo!您必须自己应用更改。
    • @DarkDust 我不会说任何一种方法都是错误的,注册通知您最终需要管理更多的东西,比如注册然后删除观察者。当您可以直接从一个代表那里完成时,代码就会少很多。现在关于您的问题,该方法将具有带有stringByReplacingCharactersInRange 的最新字符串。检查修改后的代码。
    【解决方案4】:

    斯威夫特 3.0

    流程 1

    创建 UITextfiled 的 IBOutlet 并将 Target 添加到文本字段。

     m_lblTxt.addTarget(self, action: #selector(self.textFieldDidChange), for: UIControlEvents.editingChanged)
    
     func textFieldDidChange(textField:UITextField)
     {
         NSLog(textField.text!)
     }
    

    流程 2

     m_lblTxt.delegate = self
    
     //MARK: - TextField Delegates
     func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool 
     {
          print(textField.text!)
          return true
     }
    

    【讨论】:

      【解决方案5】:

      这可以在 Interface Builder 中对 UITextFieldEditing Changed 事件完成。从它拖到你的代码并创建一个IBAction

      例如:

      @IBAction func textFieldChanged(_ sender: UITextField) {
        print(sender.text)
      }
      

      此事件与此处其他答案中的描述相同,.text 属性在触发时包含更新的文本输入。这可以帮助清理代码混乱,不必以编程方式将事件添加到视图中的每个UITextField

      【讨论】:

        【解决方案6】:

        您可以创建一个变量来存储原始字符串,然后向通知中心注册以接收UITextFieldTextDidChangeNotification事件:

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

        然后,创建一个接收通知的方法,并将文本字段的当前值与原始值进行比较

        -(void) updateButton:(NSNotification *)notification {
               self.myButton.enabled = ![self.myTextField.text isEqualToString:originalString];
        }
        

        当视图控制器被释放时,不要忘记取消注册通知。

        [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
        

        【讨论】:

          【解决方案7】:

          你可以像这样NSString *changeTemp添加一个类成员,然后

          changetemp = textfield;
          
          if( change temp != textfild ){
              changetemp=textfild;
              NSLog(@" text is changed"
          } else { 
              NSLog(@" text isn't changed"):
          }
          

          【讨论】:

            猜你喜欢
            • 2015-01-15
            • 2017-10-15
            • 1970-01-01
            • 1970-01-01
            • 2011-10-24
            • 1970-01-01
            • 1970-01-01
            • 2012-12-06
            • 2016-04-19
            相关资源
            最近更新 更多