Update property bound from text field without needing to press Enter

孤街醉人 提交于 2020-01-05 07:17:08

问题


I have a text field and I bind it to an NSString instance variable.

When I type in the text field, it does not update the variable. It waits until I press the Enter key. I don't want to hit Enter every time.

What do I need to change in order to make the binding change value immediately?


回答1:


By default, the value binding of an NSTextField does not update continuously. To fix this, you need, after selecting your text field, to check the "Continuously Updates Value" box in the Bindings Inspector under the Value heading:


However, most often, what you really want to do is update the property to which the text field is bound when the user has finished editing and presses a button ("Save" or "OK", for example). To do this, you needn't continuously update the property as described above, you just need to end editing. 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

So if for example you had a "Save" button targeting your view controller's method -save:, you would call

- (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:


The previous answer is beautiful, and I learned from it about tricking the Window/View/Document system to end-editing on everything at the programmer's will.

However, the default responder chain behavior (including the preservation of the first responder until the USER moved their focus to something else) is fundamental to the Mac's "look and feel" and I wouldn't mess with it lightly (I swear I did very powerful things in responder-chain manipulation, so I don't say that out of fear.)

In addition - there is even a simpler method - that does not require changing the binding. In the Interface-builder, select the text field, and select the "Attribute Inspector" tab. You'll see the following:

Checking the red-circled "continuous" will do the trick. This option is basic and older even than binding, and its main use is to allow validator object (a whole new story) to validate the text and change it on the fly, as the user types. When the text-field calls validator calls, it also updates bound values.



来源:https://stackoverflow.com/questions/14049913/update-property-bound-from-text-field-without-needing-to-press-enter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!