Group Group Group Group Group Group Group Group Group

How do I open a window on button click from other window

I am currently trying to develop an application which should open main window on clicking button from other window and close that other window.

My AppDelegate.h file looks like this.

    #import<Cocoa/Cocoa.h>

    @interface AppDelegate : NSWindowController <NSApplicationDelegate,NSWindowDelegate>

    @property (weak) IBOutlet NSWindow *tempwin; //Reference to window which should be shown

    - (IBAction)showwin:(id)sender; //Method to show window
     @end

My AppDelegate.m looks like this

#import "AppDelegate.h"
@interface AppDelegate ()

@property (weak) IBOutlet NSWindow *window1; //Main Window
@end

@implementation AppDelegate

- (void)windowDidLoad{
    NSLog(@"window loaded");
    [super windowDidLoad];
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application
    [_tempwin setIsVisible:NO]; //Not to show this window on app open
    NSLog(@"1");
}

- (void)applicationWillTerminate:(NSNotification *)aNotification {
    // Insert code here to tear down your application
    NSLog(@"2");
}

- (void)windowWillClose:(NSNotification *)notification{
    NSLog(@"window will close");
}

- (BOOL)windowShouldClose:(NSWindow *)sender{
    NSLog(@"should close window");
    return YES;
}

- (IBAction)showwin:(id)sender {
    
    [_window1 orderOut:self]; 
    [_tempwin makeKeyAndOrderFront:self];
    [NSApp activateIgnoringOtherApps:YES];
}
@end

Is this the correct way to achieve the thing or any other better way is there? Also When I click the close button on window I am not receiving “windowWillClose” notification.

You made your delegate / window controller one and the same? While it’s technically possible, I’m not sure it’s a good pattern.

Could you clarify what is the purpose of another window launching the “main window” (technically at this point it would really be a secondary)? Is this first window always open when the app runs? Would you be ok with letting Storyboards handle this?

@robertomachorro I am trying to create a login window. Only when the user is authenticated, I want the app to display the Main Window. I’m not using Storyboard for my application, I use .xib file. I created my Main Window first and now I wanted login feature to access main window. So I created a new Window with login fields and button.When I try to run the app, Both gets displayed simultaneously on the screen. I want only to show login screen. Only if user is authenticated, I want to show main Window.

I understand now. It’s been a while since I’ve used XIBs, have you tried opening the main window and launching the login as modal? That way the main is not accessible.

If you are open to building it in Storyboards, it becomes cleaner and easier, since you are essentially using one window but different views within. Let me know and I could share a sample.

hi @vivekstorm, the key here is the rootviewController, have you tried to instead of a new window swap the rootViewControllers?

cheers,

I tried launching login as NSAlert, but I was not able to create more than 1 TextBox inside NSAlert box. So now I created new .XIB file for login. I will try the method of building in Storyboards. If you could share any sample using Storyboards, It would be helpful for me.

I will try that. But now I created new .xib file for login window. I will try swapping the mainController with loginController. Thank you @jayantvarma , I will check that.

@vivekstorm please take a look at the sample project I uploaded to GitHub. I took two approaches: Storyboard segue and rootViewController swapping (@jayantvarma mentions that above as well).

In the end, rootViewController swap is the simplest and least amount of code, literally:

if let controller = self.storyboard?.instantiateController(withIdentifier: "LoggedInView") as? ViewController {
	self.view.window?.contentViewController = controller
}

Make sure you setup a Storyboard Identifier in your view controller storyboard. If you are curious about the Segue approach, see the commit prior to last. For an explanation on the using Segue to replace, take a look at this Stack Overflow post.

Edit: In Objective-C:

- (IBAction)checkCredentials:(id)sender {
	NSViewController *controller = [[self storyboard] instantiateControllerWithIdentifier:@"LoggedInView"];
	self.view.window.contentViewController = controller;
}