Cocoa NSOutlineView 中的文本菜单和修改字体

Cocoa text menu and modifying fonts in NSOutlineView

系统提供的文本菜单通过发送许多消息来工作,例如 changeFont: modifyFont: 和 addFontTrait: 在第一响应者链上,直到到达 NSTextView。

我想扩展它以控制我的 NSOutlineView 中的行样式,但我只能覆盖 changeFont: 在我的 window 控制器中并拦截消息(也许是一个更好的地方来做这个但是现在有效)。这适用于更改字体,但使用 modifyFont: 和 addFontTrait: 的其他菜单项(如 Bold、Bigger、Smaller)从未在 window 控制器中被调用,因此我无法修改它们的行为以处理大纲看法。有趣的是,它们在菜单中看起来是可选的,但只有 changeFont: 被调用,据我所知,我需要从 NSMenuItem 获取一个标记值,它是方法 modifyFont: 和 addFontTrait: 的发送者。

有谁知道如何通过在任何地方调用其他方法来实现此功能?谢谢!

这记录在 Cocoa Text Architecture Guide: Font Handling – Handling Font Changes 中。 -addFontTrait:-modifyFont: 消息不会向上发送响应链。它们被直接发送到字体管理器。字体管理器记下请求的修改并向响应链发送 -changeFont:

您应该只需要按原样实施 -changeFont:

您没有从菜单项中获取标签。字体管理器就是这样做的。这就是字体管理器内部记录的信息来源。

您的 -changeFont: 方法应该在字体管理器上调用 -convertFont:,传递当前字体。该方法将 return 根据记录的更改请求修改新字体。您将为所有应该受影响的字体执行此操作。 (例如,您可能选择了多种字体。)

您通常无法直接访问请求的修改,例如 "add the Bold trait" 或 "make the font bigger"。

您可以通过子类化 NSFontManager 并在应用程序启动的早期将您的子类传递给 +[NSFontManager setFontManagerFactory:] 来自定义字体管理器。在您的自定义字体管理器中,您可以单独跟踪各种操作消息请求的更改,例如 -addFontTrait:。您可以在此处检查 sendertag。然后,在您的大纲视图中,您可以查询 -changeFont: 的发件人的属性,在验证它是您的子类的实例之后,以确定请求了哪些更改。

不过请记住,您的自定义子类将在整个应用程序中使用,而不仅仅是您的大纲视图。因此,您的自定义设置应该 除了 NSFontManager 的正常行为之外,而不是 而不是 ,因此它不会破坏东西.