神秘的第一响应者改变

时间:2014-07-23 06:17:43

标签: objective-c macos cocoa first-responder

我目前正在制作偏好设置窗格。我希望自定义NSView子类在启动我的首选项窗格时具有First Responder状态。我将我的观点设置为第一响应者(在我的NSPreferencePane子类中):

- (void)didSelect {
    NSLog(@"Before: %@", self.mainView.window.firstResponder);

    [self.keyboardView.window makeFirstResponder:self.keyboardView];

    NSLog(@"After: %@", self.mainView.window.firstResponder);
}

此后我定期检查当前的First Responder,似乎在didSelect完成后不久,First Responder被更改为我的NSPreferencePane的mainView。我的程序中没有任何内容导致此更改。这是输出:

Before: <NSTextView: 0x60000013dce0>
//presumably the System Preferences search field.
After: <AMKeyboardView: 0x608000321a40>
//successfully set to the desired AMKeyboardView.
<NSView: 0x61000013ea00>
//<--- magic change to mainView, for seemingly no reason.

在Interface Builder中,我的窗口有一个名为initialFirstResponder的插座。我无法将此插座设置为任何内容,因为我的视图是以编程方式添加的,并且Interface Builder无法访问。我怀疑缺少连接会导致默认行为,将第一个响应者设置为mainView。

我该怎么做才能解决这个问题?

1 个答案:

答案 0 :(得分:1)

在查看源代码Secrets Preference Pane之后,我找到了在打开首选项窗格时将自己的搜索框设置为第一个响应者的方法。我通过添加到我的didSelect方法将此方法应用于我自己的pref窗格:

[self.mainView.window performSelector:@selector(makeFirstResponder:)
                           withObject:self.keyboardView
                           afterDelay:0.0];

......它有效!但是,我不知道为什么它的工作原理。我假设0.0延迟实际上并不是真正的瞬间,这使得这个performSelector在发生神秘的第一响应者更改后运行。

我想这可以回答我的问题,但会引出一个新的问题:为什么这会起作用?