How to load and show window from xib file - cocoa

I have made a window xib and cocoa class file (nswindowcontroller) and need to show the window from xib with an button action from main window.

In your main NSWindowController:
In the interface:
#property (nonatomic, strong) CustomWindowController *windowController;
In the implementation:
- (IBAction)didPressOpenWindowButton:(id)sender {
CustomWindowController *wc = [[CustomWindowController alloc] init];
[wc showWindow:nil];
[wc.window makeKeyAndOrderFront:nil];
_windowController = wc;
}
Connect your IBAction to your NSButton in the main window.

Related

How to change UIImageView with a button in a another view

I've search the web a day for it but I can't find it:
How Can I change a UIImageView with a button in a another view on Xcode.
I'm new to Xcode.
Add this to your header file in the ImageView ViewController, and connect it:
#property (nonatomic, retain) IBOutlet UIImageView *imageView;
Add to the other ViewController's .m file (don't forget to import your first file):
- (IBAction)btnPressed {
TheOtherViewController *vc = [[TheOtherViewController alloc] init];
vc.imageView.image = [UIImage imageNamed:#"MyImage"];
}

Open NSWindowController from NSMenu

I'm with a NSMenu in an agent application (without the icon in the dock). When a button from this menu is tapped, I want to show a generic NSWindowController.
My menu button action:
- (IBAction)menuButtonTapped:(id)sender {
MyWindowController *myWindow = [[MyWindowController alloc] initWithWindowNibName:#"MyWindowController"];
[myWindow showWindow:nil];
[[myWindow window] makeMainWindow];
}
But the window just "flashes" in the screen (it shows and disappears really fast).
Any solution?
The reason the window is showing up for a split second and then disappearing has to do with ARC and how you go about creating the instance of the window controller:
- (IBAction)menuButtonTapped:(id)sender {
MyWindowController *myWindow = [[MyWindowController alloc]
initWithWindowNibName:#"MyWindowController"];
[myWindow showWindow:nil];
[[myWindow window] makeMainWindow];
}
Under ARC, the myWindow instance will be valid for the scope where it is defined. In other words, after the last [[myWindow window] makeMainWindow]; line is reached and run, the window controller will be released and deallocated, and as a result, its window will be removed from the screen.
Generally speaking, for items or objects you create that you want to "stick around", you should define them as an instance variable with a strong property.
For example, your .h would look something like this:
#class MyWindowController;
#interface MDAppController : NSObject
#property (nonatomic, strong) MyWindowController *windowController;
#end
And the revised menuButtonTapped: method would look something like this:
- (IBAction)menuButtonTapped:(id)sender {
if (self.windowController == nil) {
self.windowController = [[MyWindowController alloc]
initWithWindowNibName:#"MyWindowController"];
}
[self.windowController showWindow:nil];
}
Use this:
[[myWindow window] makeKeyAndOrderFront:self];

NSWindowController's window released immediately

I'm trying to open a window using a NSWindowController in my app delegate.
I created a basic NSWindowController with an associated NIB and try to show the window that way:
#implementation MyAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Show the main window from a separate nib
MyWindowController * theWindowController = [[MyWindowController alloc] initWithWindowNibName:#"MyWindowController"];
[theWindowController showWindow:self];
}
#end
When I launch the app, the window of MyWindowController only appears for a fraction of second (seems to be released as soon as it launches).
Using ARC, how could I force the window to stick around and not be flushed right away? I do not use NSDocuments and I want to be able to use many of these MyWindowController concurrently.
You need to add a property to your app delegate (or some other object that's going to stick around for the lifetime of your app) that retains theWindowConroller. For example:
#interface MyAppDelegate : NSObject
#property (strong, nonatomic) MyWindowController * windowController;
#end
Then set this property when you initialize the window controller.
#implementation MyAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Show the main window from a separate nib
self.windowController = [[MyWindowController alloc] initWithWindowNibName:#"MyWindowController"];
[theWindowController showWindow:self];
}
#end

Creating a UITabBarController using a NIB outside of AppDelegate?

Still new to iOS programming, and despite copious amounts of research, I have run in to another roadblock.
What I want to implement:
I want a UITabBarController that gets loaded when I navigate from the main UI. I would also like to use a NIB to define its properties.
All of the examples I can find put the UITabBarController in the AppDelegate, but I would not like to load it unless it gets used. I also dont know if all of the UIGestureRecognizers would remain active if I just did it modally (I cant get a working implementation).
What I have so far
First, I load an initial loading view from AppDelegate
AppDelegate.h
#class InitialViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UIViewController *viewController;
#end
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[InitialViewController alloc] initWithNibName:#"InitialViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
From this view, as I am just making a skeleton of the UI, I have two buttons, one goes to what would be the main interface, and the other to the UITabBarController.
InitialViewController.h
#interface InitialViewController : UIViewController
- (IBAction)toMain:(id)sender;
- (IBAction)toTabs:(id)sender;
#property (strong, nonatomic) UIViewController *mviewController;
#property (strong, nonatomic) UIViewController *tviewController;
#end
InitialViewController.m
- (IBAction)toMain:(id)sender {
self.mviewController = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
[[[UIApplication sharedApplication] delegate] window].rootViewController = self.mviewController;
}
- (IBAction)toTabs:(id)sender {
self.tviewController = [[tabViewController alloc] initWithNibName:#"tabViewController" bundle:nil];
[[[UIApplication sharedApplication] delegate] window].rootViewController = self.tviewController;
}
On loading MainViewController, it behaves exactly like I want. But when I load the tab view, I get one long tab at the bottom and a black background. I can add in things in viewdidload, like changing the background color, but no actual tabs or views linked to the tabs in the XIB.
I suspect there is something I am missing in two areas: in the tab .h, and some linking associated with that in interface builder. Or setting a new rootViewController isnt enough.
tabBarController.h
#import <UIKit/UIKit.h>
#interface iPodViewController : UITabBarController <UITabBarControllerDelegate>
#end
If someone can point me in the right direction and/or show me an implementation that works, I would be most grateful.
-- as a note, when I go in to the tabbar.xib, and use the assistant editor, it opens InitialViewController.h --
Unlike other view controllers (e.g. UITableViewController) you should not subclass the UITabViewController. Therefore, unlike you other view controllers, you don't subclass and then make your subclass the owner of the nib, pointing at the view in the nib, with a customised view.
Instead, for whichever class that you want to own your UITabBarController, add a plain, vanilla UITabBarController as an outlet property on this class. (e.g. your app delegate).
Then create a nib file and drag a UITabBarController object into the nib. Set the owner of the nib to be the class that you want to own your tab bar controller (e.g. your app delegate) and connect the outlet you created as a property to the tab bar controller in the nib.
#interface myTabOwningClass
#property (strong, nonatomic) IBOutlet UITabBarController myTabBarControllerOutlet;
Now at the point you want to create and display your tab bar controller, use the following method:
[[NSBundle mainBundle] loadNibNamed:#"MyTabControllerNib" owner:myTabOwningClass options:nil];
This will initialise the property (i.e. myTabBarControllerOutlet in our example) on the owning class and load the tab bar controller from the nib, including all sub view controllers for each tab etc. that you have defined in the nib.

Switching between two NSWindows

I am making a simple mac app in which i want to switch windows.
I have two NSWindowController class MainWindow and DetailWindow
I am using this code :
MainWindow class:
//MainWindow.h
#class DetailWindow;
#interface MainWindow : NSWindowController{
IBOutlet NSButton *btn1;
DetailWindow *detailwindow;
}
#property (nonatomic, retain) IBOutlet NSButton *btn1;
- (IBAction)btn1Event:(id)sender;
//MainWindow.m
#implementation MainWindow
#synthesize btn1;
- (IBAction)btn1Event:(id)sender {
if (!detailwindow) {
detailwindow = [[DetailWindow alloc] initWithWindowNibName:#"DetailWindow"];
}
[detailwindow showWindow:self];
}
#end
DetailWindow Class:
//DetailWindow.h
#class MainWindow;
#interface DetailWindow : NSWindowController{
IBOutlet NSButton *backbtn;
MainWindow *mainwindow;
}
#property (nonatomic, retain) IBOutlet NSButton *backbtn;
- (IBAction)back:(id)sender;
//DetailWindow.m
#implementation DetailWindow
#synthesize backbtn;
- (IBAction)back:(id)sender {
if (!mainwindow) {
mainwindow = [[MainWindow alloc] initWithWindowNibName:#"MainWindow"];
}
[mainwindow showWindow:self];
}
#end
Now the problem is when i click backbtn on DetaiWindow it will open a new MainWindow.
So i have two MainWindow on screen.
I want just main window at front when i click backbtn.
Any help??
Thank you..!!
Your basic problem is that each window is assuming that it is its own job to create the other. Each has an ivar for the other, but there's no external access to it -- via a property or being an IBOutlet or anything else -- so it always starts out as nil, and a new copy gets created instead of reusing the old one.
There are any number of ways to get around this. Probably the easiest would be to create both windows in Interface Builder and link them up there, having made the ivars IBOutlet. Then you know you never have to create them in code at all.
However, purely on the basis of inertia, here's an alternative that sticks closer to what you've got already. Note that I've assumed for simplicity that mainWindow always exists first. If not, you'll have to duplicate the process the other way around.
//MainWindow.h
#class DetailWindow;
#interface MainWindow : NSWindowController
{
IBOutlet NSButton *btn1;
DetailWindow *detailwindow;
}
#property (nonatomic, retain) NSButton *btn1;
- (IBAction)btn1Event:(id)sender;
//MainWindow.m
#implementation MainWindow
#synthesize btn1;
- (IBAction)btn1Event:(id)sender
{
if (!detailwindow)
{
detailwindow = [[DetailWindow alloc] initWithWindowNibName:#"DetailWindow"];
// having created the other window, give it a reference back to this one
detailWindow.mainWindow = self;
}
[detailwindow showWindow:self];
}
#end
//DetailWindow.h
#class MainWindow;
#interface DetailWindow : NSWindowController
{
IBOutlet NSButton *backbtn;
MainWindow *mainwindow;
}
#property (nonatomic, retain) NSButton *backbtn;
// allow the main window to be set from outside
#property (nonatomic, retain) MainWindow *mainWindow;
- (IBAction)back:(id)sender;
//DetailWindow.m
#implementation DetailWindow
#synthesize backbtn;
#synthesize mainWindow;
- (IBAction)back:(id)sender
{
// no window creation on the way back
NSAssert(mainWindow, "mainWindow not set!");
[mainwindow showWindow:self];
}
#end
Untested, so usual caveats apply.
You have to call orderFront: method with self object on main window.
To do this you must find a reference to the main window. A way to do this is:
[NSApp mainWindow];
This call will return you a pointer to your main window (If you did something incorrect, you could have to cycle through the [NSApp windows] array in order to search for your main window).
When you have found the window, send it a orderFront message, by doing (supposing the code above returns the correct window, as explained before).
[[NSApp mainWindow] orderFront:self];
and the window should magically order front.

Resources