Apple TextEdit工具栏来源疑问:为何未在源码nib文件中找到?
嘿,我刚好研究过TextEdit的源码,这个问题我能帮到你!
Apple官方的TextEdit工具栏并不是在nib文件里静态定义的,它是通过AppKit提供的系统级文本编辑组件动态生成的,核心原因有这几点:
系统预定义的工具栏项:TextEdit注册了AppKit为文本编辑场景提供的标准工具栏标识符,比如字体选择器(
NSToolbarFontItemIdentifier)、颜色选择器(NSToolbarColorItemIdentifier)、标尺切换(NSToolbarRulerItemIdentifier)这些。你可以在源码的Document.m或者TextEditAppDelegate.m里找到NSToolbar相关的注册逻辑,比如toolbarAllowedItemIdentifiers:和toolbarDefaultItemIdentifiers:方法,这些方法告诉系统要加载哪些原生组件,不需要手动在nib里拖控件。与NSTextView深度绑定:这些工具栏控件会自动和当前编辑的
NSTextView关联,比如字体选择器会实时同步选中文本的字体,颜色选择器直接修改文本颜色,都是系统文本框架自带的逻辑,不需要额外编写复杂代码。你的实现里没有这些选项,大概率是因为没注册这些系统默认的工具栏项。强制显示的逻辑:TextEdit的工具栏之所以无法隐藏,是因为它的代码里做了特殊处理——要么通过
NSUserDefaults固定了工具栏的显示状态,要么拦截了隐藏工具栏的系统操作,同时设置toolbar.autosavesConfiguration = YES来保存用户的工具栏配置,但默认就是强制显示的。
另外关于标尺:TextEdit的标尺按钮直接绑定到NSTextView的rulersVisible属性,而你的实现需要通过菜单调出,只是因为你没把这个系统自带的工具栏按钮添加进去而已。
给你个简单的代码示例,要是想在自己的编辑器里实现类似的工具栏,在你的Document类里可以这么写:
- (void)windowControllerDidLoadNib:(NSWindowController *)aController { [super windowControllerDidLoadNib:aController]; // 初始化工具栏 NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"MyTextEditorToolbar"]; toolbar.delegate = self; toolbar.autosavesConfiguration = YES; [aController.window setToolbar:toolbar]; } // 允许的工具栏项标识符 - (NSArray<NSToolbarItemIdentifier> *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar { return @[NSToolbarFontItemIdentifier, NSToolbarColorItemIdentifier, NSToolbarRulerItemIdentifier, NSToolbarSeparatorItemIdentifier]; } // 默认显示的工具栏项 - (NSArray<NSToolbarItemIdentifier> *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar { return @[NSToolbarFontItemIdentifier, NSToolbarColorItemIdentifier, NSToolbarRulerItemIdentifier]; }
这样系统就会自动生成带字体、颜色、标尺按钮的原生工具栏啦!
内容的提问来源于stack exchange,提问作者Mandroid

