更新字段时,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 不更新?