casraf
casraf

Reputation: 21694

How can I set a menu item click to respond to IBAction from another class?

I'm pretty new to XCode/Objective-C/Cocoa. I want to implement a settings window for my app.

I have a MainMenu.xib which also holds my main Window. From the menu, I want to open a settings window. I created Settings.xib and appropriate .h and .m files to hold what that window would do.

Settings.h:

#import <Cocoa/Cocoa.h>

@interface Settings : NSWindowController <NSApplicationDelegate>

-(IBAction)openSettings:(id)senderId;

@property (nonatomic, retain) Settings *thisWindow;

@end

Settings.m:

#import "Settings.h"

@implementation Settings

- (void)windowDidLoad {
    [super windowDidLoad];

    // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}

// open preferences window
- (IBAction)openSettings:(id)senderId
{
    _thisWindow = [[Settings alloc] initWithWindowNibName:@"Settings"];
    [_thisWindow showWindow:self];
}

@end

I dragged my Preferences menu item to first responder, and selected openSettings: from there. However, the item is still disabled and I'm pretty sure it's because I did nothing to link the Settings interface to my MainMenu.xib, which works with AppDelegate.h/m.

How do I make this work? All other solutions I found didn't quite work for me.

Upvotes: 0

Views: 1058

Answers (3)

casraf
casraf

Reputation: 21694

I ended up using my AppDeleate.m to open the dialog instead. I linked the menu button to the AppDelegate object in the interface builder, and used openSettings:. Here's how it looks:

// open preferences window
- (IBAction)openSettings:(id)senderId
{
    _settingsWindow = [[Settings alloc] initWithWindowNibName:@"Settings"];
    [_settingsWindow showWindow:self];
}

In AppDelegate.m, instead of Settings.m.

Upvotes: 0

A O
A O

Reputation: 5698

Okay so in your mainwindowcontroller, declare a property of type NSWindowController *settingsWindow. Init it with the corresponding xib.

Then create a method called -(void)openSettings, with one line [self.settingsWindow showWindow:self];

Then also in your mainWindowController initialization, init a NSMenuItem, and set it's action to openSettings. Then add that NSMenuItem to the Mainmenu where you'd like programmatically, like this

//mainMenu is your application's menu-- if you switched index to 1 it would be the 'File' menu
NSMenu *mainMenu = [[[NSApp mainMenu] itemAtIndex:0] submenu];
[mainMenu insertItem:newItem atIndex:4];

Upvotes: 0

Daniyar
Daniyar

Reputation: 3003

If I understand you clear you want to store your MainMenu and MainWindowController in a two separate classes.

  1. Open your main menu nib-file. Remove window from the object tree.
  2. Check in Project Settings -> General -> Main interface is still your MainMenu (without .xib-extension).
  3. Create (implement) your custom MainWindowController class (with a nib-file may be).
  4. Open AppDelegate class. In - (void)applicationDidFinishLaunching:(NSNotification *)aNotification method create an instance of main window controller class, show the window

Use this code below

MainWindowController *controller=[[MainWindowController alloc] initWithNibName:@"MainWindowController"];
[controller showWindow:nil];
[controller.window makeKeyAndOrderFront:nil];

Here it is.

Upvotes: 0

Related Questions