【问题标题】:UITextField "value changed" not firing when field is updated更新字段时,UITextField“值已更改”未触发
【发布时间】:2011-11-22 09:01:29
【问题描述】:

我有一个IBAction,已连接到Interface Builder 中的UITextField 元素。 (触发“值改变”事件)

我还有一个UISlider,它会在调整 TextField 元素的值时自动更新它。

当我运行我的应用程序时,当我调整滑块时 TextField 确实会更新,但发生这种情况时不会触发“值更改”事件。当我手动编辑 TextField 时,值更改事件也不会触发。 (尽管使用 Did Editing End 触发器确实会触发它)。

我的问题是,如何让值更改触发器在 TextField 的编程更新以及用户调整值时触发。

【问题讨论】:

  • 嗨,你为什么不使用 UITextFieldDelegate 方法?
  • 它们有不同的用途。 shouldChangeCharactersInRange 允许您决定是否应该发生更改,您需要自己计算结果。因此,如果更改总是会发生,并且您只关心更改后的值是什么,那么使用UIControlEventEditingChanged 肯定会更容易。

标签: objective-c ios cocoa-touch interface-builder


【解决方案1】:

不要将UIControlEventValueChanged 用于UITextField。你要的是UIControlEventEditingChanged

【讨论】:

  • 我不是在争论是否有效,但我只是想知道为什么会这样?
  • 我试过了,当文本字段以编程方式更改时它不会触发。
  • 正确,设计上没有调用任何目标/动作事件来进行程序化更改。
  • 这应该是公认的答案。 UITextFieldDelegate 做了完全不同的事情。
【解决方案2】:

要获得EditingChanged textfield event,我建议将选择器添加为

[textField addTarget:self action:@selector(textChanged:) forControlEvents:UIControlEventEditingChanged];

随着文本字段值的更改,您将从textChanged: 选择器中获得更改后的值。

-(void)textChanged:(UITextField *)textField
{
    NSLog(@"textfield data %@ ",textField.text);
}

【讨论】:

  • 最简单的解决方案,并在您期望的时候触发!
  • 我想知道如果它不起作用,为什么他们有值更改事件
【解决方案3】:

如果您将委托分配给文本字段,请注意(当您从下面的委托方法返回 NO 时,将不会触发事件(编辑更改)。请考虑在您返回 NO 时调用事件侦听器这个方法

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

【讨论】:

  • Editing Changed 事件不会被触发,因为字段 没有改变 -- 这就是返回 NO 的作用!
  • @olie - 但有时您在该委托方法中以编程方式更改字段,然后返回 NO 以覆盖用户的默认文本。这是我的情况,这个答案解决了问题。
  • 当然,但这不是 编辑 更改。如果你想这样做,你的代码也应该在委托上调用更改的选择器。这样,您就可以完全掌控。
【解决方案4】:

一个老问题,但我找到的第一个搜索结果,没有一个答案是令人满意的。我发现这个解决方案效果最好:Swift UITextField subclass handle text change programmatically

覆盖 UITextField 的文本属性以添加一个 didSet(),并从那里调用您的值更改函数。

  override open var text: String? {
        didSet {
            myValueDidChange()
        }
    }

【讨论】:

    【解决方案5】:

    虽然以编程方式分配值,但在这种情况下,textFieldDidChange 永远不会被调用,因为实际上 textField 并没有改变。对于这个外部事件需要通过

    例如,textfield.sendActions(for: .editingChanged) 这将触发编辑更改事件,即使在以编程方式更改值后也会调用 textFieldDidChange。

    在哪里应用这个事件

    为文本字段赋值后,例如,textfield.text = "some value"

    【讨论】:

      【解决方案6】:

      斯威夫特 4:

      class YourViewController: UIViewController {
          // MARK: Outlets
          @IBOutlet weak var titleTextField: UITextField!
      
          // MARK: View lifecycle
          override func viewDidLoad() {
              super.viewDidLoad()
              titleTextField.delegate = self
          }
      }
      
      // MARK: UITextFieldDelegate methods
      extension YourViewController: UITextFieldDelegate {
          func textField(_ textField: UITextField,
                         shouldChangeCharactersIn range: NSRange,
                         replacementString string: String) -> Bool {
              print("changed")
              return true
          }
      }
      

      【讨论】:

        【解决方案7】:

        按照 TheRonin 的建议,使用 UITextFieldDelegate 并实现以下方法

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

        【讨论】:

        • 我是否在我的视图控制器中实现这个?
        • 是的。在 .h 文件接口声明中添加<UITextFieldDelegate>。通过 nib 文件将文本字段的委托设置为文件所有者。在 viewcontroller 中实现上述方法。
        • 以编程方式更新文本字段时这是否也有效?
        • 使用这个不是更合乎逻辑吗? UITextFieldTextDidChangeNotification ,但是我不确定如何实现它。
        • 这个方法的问题是它被调用之前输入的字符被提交。也就是说,如果您输入了fo,然后输入了o,那么textField.text 仍然是fo,而不是foo。您必须手动应用更改以获取文本字段将设置为的字符串。
        【解决方案8】:

        对于 Swift 3

        textField.addTarget(self, action: #selector(textChanged), for: .valueChanged)
        
        func textChanged() { 
         .... 
        }
        

        【讨论】:

        • 当你想在编辑时获得输入,你需要使用for: .editingChanged
        • @ChangnamHong 现在不行了,你应该使用.valueChanged
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-14
        • 2014-02-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多