即使设置了可编辑行为,也无法在NSPopover上编辑NSTextField

age*_*-10 20 cocoa nstextfield nspopover

我有一个应用程序,打开popover NSTextField.文本字段不可编辑.文本字段的行为设置为Editable.我仍然可以粘贴和复制文本到这个字段,但我无法编辑它.

谁知道,哪有什么不对?

小智 40

不确定你是否还需要答案,但可能还有其他人仍在寻找.我在apple开发者论坛上找到了一个解决方案 引用原作者:

主要问题是键盘事件的工作方式.虽然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
Run Code Online (Sandbox Code Playgroud)

这使得popover完全具有目的地.如果你需要另一个窗口,它必须对canBecomeKeyWindow响应NO,你总是可以创建一个子类.

  • 非常感谢!!如果可以的话,我会+1千倍!:) (3认同)
  • 你能详细说明如何做到这一点吗? (2认同)
  • 将文件添加到项目时,可以选择添加"Objective-C类别".这就是他所说的"canBecomeKeyWindow".复制粘贴他发布到您的代码上的内容,它应该可以工作. (2认同)

小智 8

我也挣扎了一段时间,直到我意识到这是一个错误.

但是,我发现使用您实现的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;
    }
Run Code Online (Sandbox Code Playgroud)