【问题标题】:ControlTextDidChange not called on setStringValue未在 setStringValue 上调用 ControlTextDidChange
【发布时间】:2026-01-21 10:05:01
【问题描述】:

我已经实现了一个委托及其controlTextDidChange 方法,每当我在NSTextField 中输入文本时都会调用它。

当我通过[field setStringValue:@"newText"] 以编程方式设置文本时,不会调用controlTextDidChange

你能解释一下吗?以及我应该如何以编程方式设置一个新值来触发我的委托方法 controlTextDidChange 的调用。

【问题讨论】:

    标签: objective-c xcode cocoa


    【解决方案1】:

    controlTextDidChange 委托仅在用户交互时触发,
    手动更新NSControl 不会触发委托。

    适当的解决方案

    解决方案是创建一个单独的方法来处理文本更改:

    - (void)myCustomFunction {
         // Triggered in case the text is changed,
         // no matter by user or programmatically
    }
    

    从委托中触发此方法:

    - (void)controlTextDidChange:(NSNotification *)aNotification {
        [self myCustomFunction];
    }
    

    如果文本以编程方式更改:

    [theField setStringValue:@"text"];
    [self myCustomFunction];
    

    现在您可以在同一个方法中处理这两种情况。

    【讨论】:

      【解决方案2】:

      您可以通过编程方式触发函数controlTextDidChange

      [[NSNotificationCenter defaultCenter] postNotificationName: NSControlTextDidChangeNotification
                                                          object:textFieldExample
                                                        userInfo:[NSDictionary dictionaryWithObject: [[textFieldExample window] fieldEditor:YES
                                                                                                                                 forObject:textFieldExample]
                                                                                             forKey:@"NSFieldEditor"]];
      

      这更有用,当controlTextDidChange 被多个文本字段触发时!

      【讨论】:

        【解决方案3】:

        Oliver P 的答案移植到 Swift 4.0:

        NotificationCenter.default.post(
            name: NSControl.textDidChangeNotification,
            object: textFieldExample,
            userInfo: ["NSFieldEditor":
                textFieldExample!.fieldEditor(true, for: textFieldExample)!])
        

        【讨论】:

          【解决方案4】:

          在我的情况下,调用它就足够了,没有任何 userInfo (Swift 5):

          NotificationCenter.default.post(name: NSControl.textDidChangeNotification, object: myTextField)
          

          【讨论】: