Sunday, January 13, 2013

Mac Coding: Accessing an IBOutlet from a different object

This had me stumped all day till I just figured it out after a ton of Googling, so I'm going to put it down here for anyone else out there who might be starting off on Cocoa and stuck at this point.

Here's the problem: You have the controls on your XIB file connected to IBOutlet variables in your AppDelegate. So far so good. When you change the value of the IBOutlet, the control on the screen to which you connected changes its value faithfully. No problem.

But now you have a completely different class - perhaps one with all your logic. You have an instance of this class and from within this instance you want to access the IBOutlet. For example your logic dictates that a textfield changes it's value, so you want to reach out to the IBOutlet in the AppDelegate to do this.

But this is not as simple as it sounds since you have not created any instances of the AppDelegate in your code. So how do you know which instance of the AppDelegate to reach into to set the IBOutlet property ?

Turns out you need a Singleton.

Also turns out that the application creates this singleton for you when the application launches. In other words, as soon as the application launches it creates exactly one instance of your  AppDelegate. You can refer to the Singleton instance with the following code:

// first create a reference to he application singleton
// and store it in the application variable
// (of course application is just a variable name - use any name

NSApplication *application;
application = [NSApplication sharedApplication];

// Next create a new empty pointer to the AppDelegate
// note that myAppDelegate will have to be the actual name
// of your delegate - so use the name you have in your code

myAppDelegate *delegate;

// Finally as the application to get you a reference to
// the delegate singleton and store it in the variable
// you just created.

delegate = [application delegate];

// Now you can access any property of the singleton
// e.g. if you have an IBOutlet in your appDelegate called txt1 referring
// to a text field, you can set it's value like this

delegate.txt1.stringValue = @"Bloody Finally!";

No comments:

Post a Comment