如何在Mac OS X上的NSTextField中启用拼写检查?

9
我有一个NSTextField,希望实现“边输边检查”拼写功能。当我载入应用程序时,可以通过菜单栏 > 编辑 > 拼写与语法 > 边打字时检查来实现。
我希望默认启用此选项。在IB中,我可以为NSTextView启用此选项,但我想在UI的这一部分使用NSTextField。
谢谢。
更新: 有人知道是否可以从Objective-C代码中编程运行菜单栏 > 编辑 > 拼写与语法 > 边打字时检查NSTextField选项吗?似乎NSTextField支持“边打字时检查拼写”选项,只是没有办法从Obj-C启用该选项。
编辑 #1
我尝试手动启用菜单,但它没有起作用:
// Focus TextField
[textField becomeFirstResponder];

// Enable Spell Checking
NSMenu *mainMenu = [[NSApplication sharedApplication] mainMenu];
NSMenu *editMenu = [[mainMenu itemWithTitle:@"Edit"] submenu];
NSMenu *spellingMenu = [[editMenu itemWithTitle:@"Spelling and Grammar"] submenu];
NSMenuItem *autoSpellingMenuItem = [spellingMenu itemWithTitle:@"Check Spelling While Typing"];
[autoSpellingMenuItem setEnabled:YES];

NSLog(@"Menu: %@", [autoSpellingMenuItem description]);
NSLog(@"Target: %@", [[autoSpellingMenuItem target] description]);

// Actually perform menu action
[[autoSpellingMenuItem target] performSelector:[autoSpellingMenuItem action]];

是否可以直接调用菜单项动作而不是使用setEnabled:YES?

上述代码输出了以下内容,不确定目标为什么为空。

App[3895:a0f] Menu: <NSMenuItem: 0x100135180 Check Spelling While Typing>
Current language:  auto; currently objective-c
App[3895:a0f] Target: (null)

解决方案

如果有其他人需要解决这个问题,下面是解决方案。通过一些NSLog记录,我发现在将NSTextField设置为firstResponder后,firstResponder实际上包含一个NSTextView,您可以在其中启用拼写检查。我假设NSTextField包含一个NSTextView子视图,它接受响应者,真正的做法应该是在NSTextField类中公开它。

// Focus TextField
[textField becomeFirstResponder];

// Enable Continous Spelling
NSTextView *textView = (NSTextView *)[self.window firstResponder];
[textView setContinuousSpellCheckingEnabled:YES];

出现的 NSTextView 称为字段编辑器。如果这个 firstResponder 转换太脆弱,您可以在 NSWindowController 中覆盖 -windowWillReturnFieldEditor:forObject: 并在那里更改设置。 - ctietze
2个回答

4
您很幸运,苹果提供了一个拼写检查类:NSSpellChecker:http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/SpellCheck/Concepts/SpellChecker.html。使用它,您可以通过使用textdidChange委托方法来检查每次用户更新文本的拼写。此外,您说您想使用NSTextField而不是NSTextView。为什么不使用可编辑的NSTextView,您可以在其中设置toggleAutomaticSpellingCorrection属性?编辑:要以编程方式更改菜单项的值,请执行以下操作:
// Enable Spell Checking
NSMenu *mainMenu = [[NSApplication sharedApplication] mainMenu];
NSMenu *editMenu = [[mainMenu itemWithTitle:@"Edit"] submenu];
NSMenu *spellingMenu = [[editMenu itemWithTitle:@"Spelling and Grammar"] submenu];
NSMenuItem *autoSpellingMenuItem = [spellingMenu itemWithTitle:@"Check Spelling While Typing"];
[autoSpellingMenuItem setEnabled:YES];

// Actually perform menu action
[[autoSpellingMenuItem target] performSelector:[autoSpellingMenuItem action]];

编辑:

似乎上述方法并没有按照预期触发该方法,目标为空(因为第一个响应者尚未设置?)。然而,可以直接发送消息,如下所示:

// Focus TextField
[textField becomeFirstResponder];

// Enable Continous Spelling
NSTextView *textView = (NSTextView *)[self.window firstResponder];
[textView setContinuousSpellCheckingEnabled:YES];

好的,NSTextView不支持焦点环属性,我不想为此情况重新发明轮子。我真的不明白为什么在使用NSTextField时,我无法以编程方式打开可以在“编辑”>“拼写和语法”菜单中访问的拼写选项。难道没有通过Obj-C代码打开该选项的方法吗? - Luke
此外,NSTextField 可以轻松处理返回事件的动作。 - Luke
我修改了代码以遍历菜单,尝试运行它后,所有对象都被设置好了,但setEnabled:YES没有起作用。请参见原问题中我的更新#1。 - Luke
看起来 setEnabled 只是设置了项目,但并没有实际执行操作。 - pheelicks
谢谢,我觉得我们已经接近了。但是[[autoSpellingMenuItem target] performSelector:[autoSpellingMenuItem action]]没有运行该操作。此外,setEnabled实际上并没有设置菜单项上的复选框。无论如何,菜单项具有一个发送动作continuousSpellChecking:连接到第一响应者。有没有办法在不使用遍历菜单的情况下运行此操作? - Luke
显示剩余8条评论

1
你尝试过利用NSTextField代理方法textDidChange:并调用它吗?
range = [[NSSpellChecker sharedSpellChecker] checkSpellingOfString:aString startingAt:0];

每次?

我指的是NSTextField而不是UITextField。这是一个Mac OS X桌面应用程序问题。 - Luke
我希望有比使用textDidChange更好的方法。我注意到默认的菜单栏已经连接到Edit > Spelling and Grammar > Check Spelling While Typing选项上的toggleAutomaticSpellingCorrection:。一旦应用程序运行,此菜单选项将与NSTextField一起工作。我想知道如何通过Obj-C代码启用官方选项。 - Luke
你可能想从你的回答中删除错误的 iPhone 建议,这样它就不会在 Google 中显示。 - Luke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接