我有一个应用程序,它使用NSTextField
. 文本字段不可编辑。文本字段的行为设置为Editable
。我仍然可以将文本粘贴和复制到此字段,但我无法编辑它。
任何人都知道,有什么问题?
我有一个应用程序,它使用NSTextField
. 文本字段不可编辑。文本字段的行为设置为Editable
。我仍然可以将文本粘贴和复制到此字段,但我无法编辑它。
任何人都知道,有什么问题?
不确定您是否仍然需要答案,但可能还有其他人仍在寻找。我在苹果开发者论坛上找到了解决方案。引用原作者的话:
主要问题是键盘事件的工作方式。尽管 NSTextField (及其所有超级视图)接收键盘事件,但它不执行任何操作。发生这种情况是因为附加弹出窗口的视图位于不能成为关键窗口的窗口中。你不能以任何方式访问那个窗口,至少我不能。因此解决方案是使用类别覆盖应用程序中每个 NSWindow 的方法 canBecomeKeyWindow。
NSWindow+canBecomeKeyWindow.h
@interface NSWindow (canBecomeKeyWindow)
@end
NSWindow+canBecomeKeyWindow.m
@implementation NSWindow (canBecomeKeyWindow)
//This is to fix a bug with 10.7 where an NSPopover with a text field cannot be edited if its parent window won't become key
//The pragma statements disable the corresponding warning for overriding an already-implemented method
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
- (BOOL)canBecomeKeyWindow
{
return YES;
}
#pragma clang diagnostic pop
@end
这使得弹出框完全响应。如果您需要另一个必须对 canBecomeKeyWindow 响应 NO 的窗口,您总是可以创建一个子类。
我也为此苦苦挣扎了一段时间,直到我意识到这是一个错误。
但是,与其依赖 NSStatusItem 视图的 isActive 状态,我发现使用已实现的 NSPopover 的 isShown 属性更可靠。
在我的代码中,我在 NSViewController 中有一个 NSPopover:
- (BOOL)canBecomeKeyWindow
{
if([self class]==NSClassFromString(@"NSStatusBarWindow"))
{
NSPopover *mainPopover = [[((AppDelegate*)[NSApp delegate]) mainViewController] mainPopover];
if(![mainPopover isShown])
return NO;
}
return YES;
}
Balazs Toth 的回答有效,但如果您将弹出框附加到 NSStatusItem.view ,则状态项将变得无响应 - 需要单击两次才能聚焦。
我在使用此解决方案时发现,当NSStatusItem变得无响应时,您可以像这样轻松地覆盖此行为
- (BOOL)canBecomeKeyWindow {
if([self class]==NSClassFromString(@"NSStatusBarWindow")) {
CBStatusBarView* view = [((CBAppDelegate*)[NSApp delegate]) statusItemView];
if(![view isActive]) return NO;
}
return YES;
}
您将检查窗口的类,如果它与NSStatusBarWindow匹配,我们可以以某种方式检查NSStatusItem是否处于活动状态。如果是,这意味着我们必须返回 YES,因为这样来自 NSStatusItem 的NSPopover将拥有所有键盘事件。
我用来检查NSStatusItem是否被单击(或处于活动状态)是在我自己的自定义视图中,我有一个 bool 值,当用户单击NSStatusItem时该值会发生变化,系统会自动检查“canBecomeKeyWindow”以及何时执行它将返回 NO并且在用户单击它后(当它返回NO时)它将更改 bool 值并在系统再次询问时返回 YES(当单击NSPopover进行NSTextField编辑时)。
旁注:
如果有人仍在寻找这个问题的答案,我正在 Swift 中工作。
在您希望该字段允许文本输入时,我使用过myTextField.becomeFirstReponder()
选择退出;只需使用myTextField.resignFirstResponder()
绝对是一个错误。那个错误报告正是我想要做的。甚至可以创建状态项和覆盖 mousdown。
我可以确认 Balazs Toth 的回答有效。我只是想知道它是否会妨碍您前进。