2

いくつかの NSTextFields を持つ Mac アプリケーション (SDK 10.10) があります。

Xib ファイル

テキスト フィールドがフォーカスを取得したときとフォーカスを外したときに通知を受け取る必要があるため、NSTextField をサブクラス化しました。

@interface MyTextField : NSTextField
@end

@implementation MyTextField

- (BOOL)becomeFirstResponder
{
    BOOL didBecomeFirstResponder = [super becomeFirstResponder];
    NSLog(@"%@ didBecomeFirstResponder = %@", [self accessibilityLabel], didBecomeFirstResponder?@"YES":@"NO");
    return didBecomeFirstResponder;
}

- (BOOL)resignFirstResponder
{
    BOOL didResignFirstResponder = [super resignFirstResponder];
    NSLog(@"%@ didResignFirstResponder = %@", [self accessibilityLabel], didResignFirstResponder?@"YES":@"NO");
    return didResignFirstResponder;
}

@end

このコードを実行して 3 つのテキスト フィールド間でタブ移動すると、コンソールに次の出力が表示されます。

firstField didResignFirstResponder = YES
firstField didBecomeFirstResponder = YES
secondField didResignFirstResponder = YES
secondField didBecomeFirstResponder = YES
thirdField didResignFirstResponder = YES
thirdField didBecomeFirstResponder = YES
firstField didResignFirstResponder = YES
firstField didBecomeFirstResponder = YES
secondField didResignFirstResponder = YES
secondField didBecomeFirstResponder = YES

TAB キーを押す (または非アクティブなテキスト フィールドの 1 つをクリックする) たびに、アプリは出力します。

<new first responder> didResignFirstResponder = YES
<new first responder> didBecomeFirstResponder = YES

そんなはずないでしょ

<old first responder> didResignFirstResponder = YES
<new first responder> didBecomeFirstResponder = YES

???

ここで何かひどく間違っていますか?

のドキュメントは- (BOOL)resignFirstResponder言う

ウィンドウでファーストレスポンダーとしてのステータスを放棄するよう求められたことを受信者に通知します。

では、なぜresignFirstResponder古いファーストレスポンダーではなく、新しいファーストレスポンダーに呼び出されるのでしょうか?

4

2 に答える 2

1

私は同じ問題を抱えていて解決策を見つけることができなかったので、それを回避しtextDidEndEditing()、同じ目的でメソッドを使用することになりました。スウィフトコード:

MyTextFieldサブクラス化して、テキスト フィールドがフォーカスを失った後にロジックを処理するプロパティをNSTextField追加します。myDelegate

class MyTextField : NSTextField
{

/// Custom delegate with other methods than NSTextFieldDelegate.
var myDelegate: MyTextFieldDelegate? = nil;

override func becomeFirstResponder() -> Bool {
    let became = super.becomeFirstResponder();
    if (became) {
        self.myDelegate?.myTextFieldDidBecomeFirstResponder(self);
    }
    return became;
}

override func resignFirstResponder() -> Bool {
    let resigned = super.resignFirstResponder();
    if (resigned) {
        self.myDelegate?.myTextFieldDidResignFirstResponder(self);
    }
    return resigned;
}

override func textDidEndEditing(obj: NSNotification) {
    super.textDidEndEditing(obj);
    self.myDelegate?.myTextFieldDidResignFirstResponder(self);
}

}

プロトコル自体:

protocol MyTextFieldDelegate
{

    func myTextFieldDidBecomeFirstResponder(textField: MyTextField);

    func myTextFieldDidResignFirstResponder(textField: MyTextField);
}

明らかに、デリゲートを使用して呼び出す代わりに、失われた/獲得したフォーカス ロジックをすぐに実装することができます (たとえば、別の境界線を描画するなど)。

手がかりはtextDidEndEditing()方法であり、別のフィールドをクリックしたとき、Enterキーを押したとき、またはタブアウトしたときにうまくいくようです。

于 2015-05-26T16:29:22.897 に答える