系统提供的文本菜单通过发送一些消息来工作,例如changeFont:modifyFont:和addFontTrait:在第一个响应链上,直到它到达NSTextView为止。
我想扩展它以控制我的NSOutlineView中的行样式,但我只能覆盖changeFont:在我的窗口控制器中拦截消息(可能是一个更好的地方,但它现在可以工作)。这适用于更改字体,但其他菜单项如Bold,Bigger,Smaller使用modifyFont:和addFontTrait:不会在窗口控制器中调用,因此我无法修改它们的行为以处理大纲视图。有趣的是,它们在菜单中看起来是可选择的,但只有changeFont:被调用,据我所知,我需要从NSMenuItem获取一个标签值,它是方法modifyFont的发送者:和addFontTrait:。
有没有人知道如何通过在其他地方调用其他方法来实现此功能?谢谢!
答案 0 :(得分:1)
Cocoa Text Architecture Guide: Font Handling – Handling Font Changes中记录了这一点。 -addFontTrait:
和-modifyFont:
消息不会在响应者链中发送。它们被直接发送到字体管理器。字体管理器记录所请求的修改并向响应者链发送-changeFont:
。
您应该只需要实现-changeFont:
。
您没有从菜单项中获取标记。字体管理器就是这样做的。这是字体管理器在内部记录的信息来源。
您的-changeFont:
方法应该在字体管理器上调用-convertFont:
,并传递当前字体。该方法将返回根据记录的更改请求修改的新字体。对于应该受影响的所有字体,您都会这样做。 (例如,您可能选择了多种字体。)
您通常无法直接访问所请求的修改,例如"添加粗体特征"或者"使字体更大"。
您可以通过继承NSFontManager
并在应用启动的早期将子类传递给+[NSFontManager setFontManagerFactory:]
来自定义字体管理器。在自定义字体管理器中,您可以单独跟踪各种操作消息(如-addFontTrait:
)所请求的更改。您可以在此处查看tag
的{{1}}。然后,在大纲视图中,您可以在验证它是您的子类的实例之后查询sender
的发件人的属性,以确定请求了哪些更改。
但请记住,您的自定义子类将在整个应用中使用,而不仅仅是大纲视图。因此,您的自定义应该在添加 -changeFont:
的正常行为,而不是而不是,因此它不会破坏内容。