【问题标题】:unlockFocus called too many timesunlockFocus 调用次数过多
【发布时间】:2014-12-30 10:40:22
【问题描述】:

我使用以下方法单击位于我的 OS X 应用程序主窗口上的 NSButton (openPanel) 以显示 NSPanel (myPanel):

- (IBAction)openPanel:(id)sender {
    [_myPanel makeKeyAndOrderFront:nil];
}

除了我第一次单击按钮(openPanel)时在调试区域中得到以下描述外,一切都按预期工作:

"unlockFocus called too many times. Called on NSButton: 0x610000141080."

Panel的属性选择如下:

Style: Utility Panel, 
Appearance:Title Bar and Shadow, 
Controls:  Close, 
Behaviour: Restorable, 
Memory: Deferred

我浏览了网络,但找不到任何解释。有谁知道为什么会发生这种情况或如何解决?

【问题讨论】:

  • 我遇到了类似的问题。 (1) 使用情节提要 (2) 仅在第一次单击按钮时发生 - 随后很好 (3) 我正在使用按钮通过 NSDocument 显示 NSSavePanel。

标签: objective-c macos nspanel


【解决方案1】:

我在使用 XCode 7.0 beta 6 使用故事板和 segue 来显示工作表时遇到了同样的问题。如果您直接从操作中打开面板,似乎会出现一些常见问题。

要解决问题,只需从主队列中打开面板:

- (IBAction)openPanel:(id)sender {
    dispatch_async(dispatch_get_main_queue(), ^{
        [_myPanel makeKeyAndOrderFront:nil];
    });
}

这也将解决 swift 和故事板中的类似问题。使用此 swift 代码调用 segue:

@IBAction func onButtonClicked(sender: AnyObject) {
    dispatch_async(dispatch_get_main_queue(), {
        self.performSegueWithIdentifier("identifier", sender: self);
    })
}

【讨论】:

    【解决方案2】:

    不确定那里发生了什么,但我会尝试这样做以显示您的 NSPanel:

    -(IBAction)openPanel:(id)sender {
    [[NSApplication sharedApplication] beginSheet:_myPanel
                                   modalForWindow:self.window
                                    modalDelegate:self
                                   didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
                                      contextInfo:nil];
    

    您还应确保为您的 NSPanel 激活 Release When Closed 复选框。 在 Interface Builder 中搜索它。

    编辑:你在你的 NSPanel 上画什么吗?设置 NSColor 或显示 NSImage ? 我的猜测是您正在显示一个 NSImage 并在这方面搞砸了一些事情:Apple Doc: lockFocus

    【讨论】:

    • 感谢您的 cmets。点击后,我确实更改了 NSButton (openPanel) 的字体颜色,如下所示: NSColor *color = [NSColor blackColor]; NSMutableAttributedString *colorTitle; NSRange 标题范围; colorTitle = [[NSMutableAttributedString alloc] initWithAttributedString:[openPanel attributesTitle]]; titleRange = NSMakeRange(0, [colorTitle 长度]); [colorTitle addAttribute:NSForegroundColorAttributeName 值:颜色范围:titleRange]; [openPanel setAttributedTitle:colorTitle];
    【解决方案3】:

    我已经解决了以下问题

    在标题中

    @interface aWindowController : NSWindowController
    {
        /* other Vars */
    
        NSOpenPanel *panel;
    }
    

    .m

    - (void)windowDidLoad {
        [super windowDidLoad];
    
        /* other stuff */
    
        /* set Panel Properties */
        panel = [NSOpenPanel openPanel];
    
        [panel setCanChooseDirectories:YES];
        [panel setCanChooseFiles:NO];
        [panel setAllowsMultipleSelection:YES];
    }
    

    在 NSButton IBACTION 中

    - (IBAction)getFiles:(id)sender
    {
        NSArray *resultArry;
    
        if([panel runModal] == NSFileHandlingPanelOKButton ){
            resultArry = [panel URLs];
            return resultArry;
        }
    
        return nil;
    }
    

    ARC 将清理面板。

    【讨论】:

    • IBACTION 调用另一个方法打开面板。
    • 此答案存在一些格式问题,使其更难阅读。
    • 问题出在 Xcode 5 和 Xcode 6 10.8 到 10.10 上。 NSPanel 行为已更改。要修复它,(1)不使用 NSPanel,(2)在 Window Controller init 上声明和初始化 NSPANEL。或者 AppDelegate 的 DidLoad。当需要面板时,设置属性并显示面板。 ARC 将在应用终止时清理 NSPanel。
    • 我认为,Panel Drawing Error,是由于 NSOpenPanel 对象尚未初始化,但尝试设置面板的属性。通过将其创建为“全局对象”并随时可以调用,将解决此问题。至少,这是我修复解锁焦点错误的方法。
    • 普通窗口不会发生失去焦点的错误。它只发生在顶部有 CALayer 的窗口上。
    【解决方案4】:

    我在使用名为 Segue 的 NSPopUpButton 时遇到了同样的问题,@Flovdis 的答案对我有用。

    这是我使用的 Objective C 代码:

    dispatch_async(dispatch_get_main_queue(), ^{
            [self performSegueWithIdentifier:@"MySegue" sender:self];
        });
    

    【讨论】:

      猜你喜欢
      • 2015-02-11
      • 2015-03-15
      • 2014-11-21
      • 2019-10-07
      • 2021-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多