是否有一种可靠的方法来检测子视图中的第一响应者更改?

Jos*_*rth 5 cocoa objective-c webview nsview first-responder

我建立一个包含其他几个子视图(自定义视图NSTextField,WebView...).当其中一个子视图是第一个响应者时,我想让我的自定义视图绘制一个不同的边框,并作为一个可以通过菜单项和键盘快捷键操作的单个项目.它看起来像这样:

+-------------+
| NSTextField |
+-------------+
| WebView     |
+-------------+
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经成功的子类NSTextField和其他通知委托时- (BOOL)becomeFirstResponder- (BOOL)resignFirstResponder被调用.这种方法不起作用WebView,因为它本身包含许多子视图 - 我不能将它们全部子类化!

是否有更好的方法来检测子视图何时更改其第一响应者状态?或者更好的方法来创建自定义视图?

Jos*_*rth 5

另一种方法是重写-makeFirstResponder:方法来NSWindow发送通知。

- (BOOL)makeFirstResponder:(NSResponder *)responder {
  id previous = self.firstResponder ?: [NSNull null];
  id next = responder ?: [NSNull null];

  NSDictionary *userInfo = @{
    BrFirstResponderPreviousKey: previous,
    BrFirstResponderNextKey: next,
  };

  [[NSNotificationCenter defaultCenter] postNotificationName:BrFirstResponderWillChangeNotification object:self userInfo:userInfo];

  return [super makeFirstResponder:responder];
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在自定义视图或视图控制器中监听通知,并检查前一个或下一个响应者是否是子视图,-isDescendantOf:needsDisplay根据需要进行设置。

但这不是一个理想的解决方案,因为自定义视图不再是独立的。它目前有效,但希望能分享更好的方法。


Kap*_*ppe 1

WebViewEditingDelegate方法都会被调用,

辞职第一响应者:

-(void)webViewDidEndEditing:(NSNotification *)notification
{

}
Run Code Online (Sandbox Code Playgroud)

当成为第一响应者时:

-(BOOL)webView:(WebView *)webView shouldBeginEditingInDOMRange:(DOMRange *)range
{
    return YES;
}
Run Code Online (Sandbox Code Playgroud)