2

テキスト フィールドがあり、それをNSStringインスタンス変数にバインドします。

テキスト フィールドに入力しても、変数が更新されません。Enterキーを押すまで待機します。毎回 Enter キーを押したくありません。

バインディングの値をすぐに変更するには、何を変更する必要がありますか?

4

2 に答える 2

4

デフォルトでは、 の値バインディングはNSTextField継続的に更新されません。これを修正するには、テキスト フィールドを選択した後、[バインディング インスペクター] の [値] 見出しの下にある [値を継続的に更新する] ボックスをオンにする必要があります。

[値を継続的に更新する] がオンになっている NSTextField 値バインディング。


ただし、ほとんどの場合、ユーザーが編集を終了してボタン (「保存」や「OK」など) を押したときに、テキスト フィールドがバインドされているプロパティを更新する必要があります。これを行うには、上記のようにプロパティを継続的に更新する必要はありません。編集を終了するだけで済みます。 Daniel Jalkut は、まさにそのようなメソッドの非常に便利な実装を提供しています

@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

たとえば、View Controller のメソッドをターゲットとする「保存」ボタンがある-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...
}
于 2012-12-29T07:28:05.633 に答える
1

前の回答は素晴らしいものでした。ウィンドウ/ビュー/ドキュメント システムを騙して、プログラマーの意志ですべての編集を終了することについて学びました。

ただし、デフォルトのレスポンダー チェーンの動作 (ユーザーがフォーカスを別のものに移動するまでファーストレスポンダーを保持することを含む) は、Mac の「ルック アンド フィール」の基本であり、私はそれを簡単にいじることはしません (誓って、非常にやりました)。レスポンダーチェーンの操作で強力なことなので、恐れては言いません.)

さらに、バインディングを変更する必要のない、さらに簡単な方法があります。Interface-builder で、テキスト フィールドを選択し、[Attribute Inspector] タブを選択します。次のように表示されます。 Interface-Builder 属性インスペクタータブ

赤丸の「連続」をチェックするとうまくいきます。このオプションは基本的なものであり、バインディングよりも古いものであり、その主な用途は、バリデータ オブジェクト (まったく新しいストーリー) がテキストを検証し、ユーザーが入力したときにその場で変更できるようにすることです。テキストフィールドがバリデータを呼び出すと、バインドされた値も更新されます。

于 2018-01-21T22:09:46.973 に答える