【问题标题】:Update property bound from text field without needing to press Enter更新从文本字段绑定的属性,无需按 Enter
【发布时间】:2012-12-27 05:41:59
【问题描述】:

我有一个文本字段,并将其绑定到 NSString 实例变量。

当我在文本字段中输入时,它不会更新变量。它一直等到我按下 Enter 键。我不想每次都按 Enter。

我需要更改什么才能立即使绑定更改值?

【问题讨论】:

    标签: objective-c cocoa cocoa-bindings nstextfield


    【解决方案1】:

    默认情况下,NSTextField 的值绑定不会连续更新。要解决此问题,您需要在选择文本字段后检查绑定检查器中值标题下的“持续更新值”框:


    然而,大​​多数情况下,您真正​​想要做的是在用户完成编辑并按下按钮(“保存”或“确定”)时更新文本字段绑定到的属性, 例如)。为此,您无需如上所述不断更新属性,只需结束编辑即可。 Daniel Jalkut provides an extremely useful implementation of just such a method:

    @interface NSWindow (Editing)
    
    - (void)endEditing;
    
    @end
    
    @implementation NSWindow (Editing)
    
    - (void)endEditing
    {
        // Save the current first responder, respecting the fact
        // that it might conceptually be the delegate of the 
        // field editor that is "first responder."
        id oldFirstResponder = [oMainDocumentWindow firstResponder];
        if ((oldFirstResponder != nil) &&
            [oldFirstResponder isKindOfClass:[NSTextView class]] &&
            [(NSTextView*)oldFirstResponder isFieldEditor])
        {   
            // A field editor's delegate is the view we're editing
            oldFirstResponder = [oldFirstResponder delegate];
            if ([oldFirstResponder isKindOfClass:[NSResponder class]] == NO)
            {
                // Eh ... we'd better back off if 
                // this thing isn't a responder at all
                oldFirstResponder = nil;
            }
        } 
    
        // Gracefully end all editing in our window (from Erik Buck).
        // This will cause the user's changes to be committed.
        if([oMainDocumentWindow makeFirstResponder:oMainDocumentWindow])
        {
            // All editing is now ended and delegate messages sent etc.
        }
        else
        {
            // For some reason the text object being edited will
            // not resign first responder status so force an 
            /// end to editing anyway
            [oMainDocumentWindow endEditingFor:nil];
        }
    
        // If we had a first responder before, restore it
        if (oldFirstResponder != nil)
        {
            [oMainDocumentWindow makeFirstResponder:oldFirstResponder];
        }
    }
    
    @end
    

    因此,例如,如果您有一个“保存”按钮针对您的视图控制器的方法 -save:,您会调用

    - (IBAction)save:(id)sender
    {
        [[[self view] window] endEditing];
        //at this point, all properties bound to text fields have the same
        //value as the contents of the text fields.
    
        //save stuff...
    }
    

    【讨论】:

      【解决方案2】:

      前面的答案很漂亮,我从中学到了如何欺骗 Window/View/Document 系统以按照程序员的意愿对所有内容进行最终编辑。

      但是,默认响应者链行为(包括在用户将注意力转移到其他东西之前保留第一响应者)是 Mac 的“外观和感觉”的基础,我不会轻易搞砸它(我发誓我在响应链操作中做了非常强大的事情,所以我不会因为害怕而这么说。)

      此外 - 还有一种更简单的方法 - 不需要更改绑定。在 Interface-builder 中,选择文本字段,然后选择“Attribute Inspector”选项卡。您将看到以下内容:

      检查红圈的“连续”就可以了。这个选项是基本的,甚至比绑定更老,它的主要用途是允许验证器对象(一个全新的故事)验证文本并在用户键入时动态更改它。当文本字段调用验证器调用时,它也会更新绑定值。

      【讨论】:

      • 将其与文本字段一起使用不会对输入其中的每个字符应用该操作,这可能是因为您将文本输入到单独的字段编辑器中。带有文本字段的“连续”基本上没有为此目的......
      • 为我工作,就像一个魅力 - 我从未创建过任何字段编辑器。只有一个文本编辑器,其会话随着焦点从一个字段移动到另一个字段。我从来没有说过它会根据输入的字符发送动作。我说将调用验证 - 绑定值将更新。行动是另一回事。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-05
      • 2010-10-08
      • 2018-05-05
      • 2012-07-11
      • 1970-01-01
      • 2012-02-10
      • 1970-01-01
      相关资源
      最近更新 更多