0

I click on a NSButton (openPanel) which is located on the main window of my OS X app to show a NSPanel (myPanel) using the following method:

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

Everything works as expected except I get the following description in the debug area only the first time I click on the button (openPanel):

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

The attributes of the Panel are selected as follows:

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

I have looked through the web but can not find any explanation. Does anyone know why this happens or how to resolve it?

Sport
  • 8,570
  • 6
  • 46
  • 65
DORI
  • 54
  • 1
  • 8
  • I am having a similar issue. (1) Using storyboards (2) Only occurs on the first button click - subsequent are fine (3) I am using the button to show a NSSavePanel via NSDocument. – Sam Jan 29 '15 at 14:22

4 Answers4

1

I had the same problem using XCode 7.0 beta 6 using storyboards and a segue to display a sheet. It seems some common problem which happens if you open the panel directly from the action.

To solve the problem, just open the panel from the main queue:

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

This will also solve similar problems from swift and storyboards. Use this swift code to call a segue:

@IBAction func onButtonClicked(sender: AnyObject) {
    dispatch_async(dispatch_get_main_queue(), {
        self.performSegueWithIdentifier("identifier", sender: self);
    })
}
Flovdis
  • 2,945
  • 26
  • 49
0

Not sure what is going on there but I would try this to show your NSPanel:

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

Also you should make sure that Release When Closed checkbox is activated for your NSPanel. Search for it in the Interface Builder.

EDIT: Are you drawing something on your NSPanel ? Setting a NSColor or showing a NSImage ? My guess is that you are displaying a NSImage and messed something up concerning this: Apple Doc: lockFocus

dehlen
  • 7,325
  • 4
  • 43
  • 71
  • thanks for your comments. I do change the font color of the NSButton (openPanel) after it has been clicked as follows: NSColor *color = [NSColor blackColor]; NSMutableAttributedString *colorTitle; NSRange titleRange; colorTitle = [[NSMutableAttributedString alloc] initWithAttributedString:[openPanel attributedTitle]]; titleRange = NSMakeRange(0, [colorTitle length]); [colorTitle addAttribute:NSForegroundColorAttributeName value:color range:titleRange]; [openPanel setAttributedTitle:colorTitle]; – DORI Dec 31 '14 at 19:43
0

I have fixed the same problem with the following

In Header

@interface aWindowController : NSWindowController
{
    /* other Vars */

    NSOpenPanel *panel;
}

In .m

- (void)windowDidLoad {
    [super windowDidLoad];

    /* other stuff */

    /* set Panel Properties */
    panel = [NSOpenPanel openPanel];

    [panel setCanChooseDirectories:YES];
    [panel setCanChooseFiles:NO];
    [panel setAllowsMultipleSelection:YES];
}

in NSButton IBACTION

- (IBAction)getFiles:(id)sender
{
    NSArray *resultArry;

    if([panel runModal] == NSFileHandlingPanelOKButton ){
        resultArry = [panel URLs];
        return resultArry;
    }

    return nil;
}

ARC will clean up the panel.

Rds
  • 1
  • 1
  • IBACTION call another method to open the panel. – Rds Jan 30 '15 at 23:42
  • 2
    There are some formatting issues with this answer which make it more difficult to read. – Ding Jan 30 '15 at 23:55
  • Problem is with Xcode 5 and Xcode 6, 10.8 to 10.10 . NSPanel behaviour changed. To fix it, (1) NOT using NSPanel, (2) declare and Init NSPANEL on Window Controller init. Or AppDelegate's DidLoad. When the panel is needed, set properties and show the panel. ARC will clean the NSPanel on App Termination. – Rds Feb 08 '15 at 23:55
  • I think, Panel Drawing Error, was a result of NSOpenPanel object was not initialized yet, but try to set panel's property. By Create it as a "global object" and ready be called up anytime, will fixed this problem. At least, this how i fixed my unlock focus error. – Rds Feb 09 '15 at 00:22
  • The lost focus error does not happen on a common window. It only happen on a windows with a CALayer on top. – Rds Feb 09 '15 at 05:38
0

I had the same problem with a NSPopUpButton that called a Segue and @Flovdis answer worked for me.

This is the Objective C code I used:

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