更新字段时,UITextField“值已更改”未触发

Posted

技术标签:

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

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

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

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

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

【问题讨论】:

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

以上是关于更新字段时,UITextField“值已更改”未触发的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift - 当 UITextField 以编程方式更新时,UILabel 字段未更新

为啥在完成块中更改 .text 字段时 UITextField 和 UILabel 不更新?

C# INotifyPropertyChanged使用方法

应用程序标识符授权值已更改?

Gtkmm ListStore,如何在其中一行中捕获该值已更改?

更改源时DataGrid更新不起作用