【发布时间】:2011-11-05 01:40:00
【问题描述】:
我有一个应用程序,它使用NSTextField 打开弹出框。文本字段不可编辑。文本字段的行为设置为Editable。我仍然可以将文本粘贴和复制到该字段,但我无法对其进行编辑。
谁知道,有什么问题?
【问题讨论】:
标签: cocoa nstextfield nspopover
我有一个应用程序,它使用NSTextField 打开弹出框。文本字段不可编辑。文本字段的行为设置为Editable。我仍然可以将文本粘贴和复制到该字段,但我无法对其进行编辑。
谁知道,有什么问题?
【问题讨论】:
标签: cocoa nstextfield nspopover
不确定您是否仍需要答案,但可能还有其他人仍在寻找。我在苹果开发者论坛上找到了解决方案。引用原作者:
主要问题是键盘事件的工作方式。尽管 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 的窗口,您可以随时创建一个子类。
【讨论】:
我也为此苦苦挣扎了一段时间,直到我意识到这是一个错误。
但是,我发现使用您已实现的 NSPopover 的 isShown 属性而不是依赖于 NSStatusItem 视图的 isActive 状态更可靠。
在我的代码中,我在 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 的回答有效。我只是想知道它是否会妨碍您前进。
【讨论】:
【讨论】: