<

Simple Binding. Cocoa GUI Application without Outlets.

Published on
27,707 Points
18,007 Views
2 Endorsements
Last Modified:
Awarded
An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Outlet.  

The normal way to use an Outlet is:  In the 64-bit Xcode, you just add a property with the IBOutlet keyword, synthesize it, and set new text via that property, as follows:

In the interface section you declare a new property:
@property (retain) IBOutlet NSTextField * text;
In the implementation section you synthesize it; that is, have the compiler generate the get/set handlers:
@synthesize text;
If you want to set text to the control, just assign the property a value:
text.stringValue = @"Hello, World!";
To get data from the control, just access the property:
NSString* str = text.stringValue;

The same can be done without manual coding.  Doing it via the IDE is sometimes necessary, and it is useful and interesting to know how to do this.  

Example 1 -- Bind a text input to a label

Let's make a testing application:

1. Create new Mac OS X Cocoa project in Xcode

New Project wizard in Xcode. Choose Mac OS X, Cocoa application template
Set the project name and save it.I named the project as TextNoOutlet (shown on the screenshots above).

2. Add a string property

In the application delegate class I have added a string:
Application Delegate Class files in the projectInitially, the application delegate class is declared (in the TextNoOutletAppDelegate.h file) as:
#import <Cocoa/Cocoa.h>

@interface TextNoOutletAppDelegate : NSObject {
    NSWindow *window;
}

@property (assign) IBOutlet NSWindow *window;

@end

Open in new window

Replace that code with:
#import <Cocoa/Cocoa.h>

@interface TextNoOutletAppDelegate : NSObject
// Few lines removed from this place
@property (assign) IBOutlet NSWindow *window;

// New property added here
@property (copy) NSString *text;

@end

Open in new window

Press Control-S to save the header file.  Press Alt-Cmd-Up to switch to the m-file.  Synthesize the property:
#import "TextNoOutletAppDelegate.h"

@implementation TextNoOutletAppDelegate

@synthesize window;

// synthesize new property
@synthesize text;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
 // Insert code here to initialize your application 
}

@end

Open in new window

New lines added to the source code have been marked with the comments.  Press Control-S here to save the modification.

3. Add the label control

In Interface Builder, click twice on the MainWindow.xib file to open it, I put the Text Field on the prototype window. Let's put a Label control under this text field. Arrange the size and locations.
Make GUI for the project in Interface Builder

4. Set up the binding

Select the text field in the prototype window. Press Command-4 to open the Binding Inspector:
Binding. Text Field control.In the Value section check the checkbox Bind To.  Press on the button on the right and in the popup menu select the application delegate named Text No Outlet Application Delegate:
Binding. Text Field control.Type text into the Key Model Path input field.  You should see something like this picture:
Binding. Text Field control.In this step, I connected the text field in my GUI with the property named 'text' from the application delegate class in my source code.

Select the label.  Press Command-4 to switch to the Binding Inspector. Check the Bind To checkbox, set the application delegate and modify the Modal Key Path in the same way as for the text field.
Binding. Text Field control.Save your work in Interface Builder (Control-S or Save in the File menu).

5. Build and Run the program

It will look like this:
Binding. Text Field control.Try to type a text in the text field, press Enter.  You will see the text reflected immediately in the label.

Example 2 -- Bind a text input to the window caption bar

Let's apply the binding to the application window:

In Interface Builder, select the window object in the Document window, press Command-4 to switch to the Binding Inspector and bind the title of the window in the same way as the label before:
Bind the window title to the text property.Save the change and Build and Run the program:
Launch the test application.Window title changed.

Example 3 -- Bind a Slider control to a Label

I'd like to show one more example, this time with the slider control.  Same principle: I will add a property, for example 'value', to the application delegate class and bind it with the slider control and a label.

The property added to the application delegate is marked with the comment in the code below:
#import <Cocoa/Cocoa.h>

@interface TextNoOutletAppDelegate : NSObject

@property (assign) IBOutlet NSWindow *window;
@property (copy) NSString *text;

// New property for the Slider control
@property (assign) NSInteger value;

@end

Open in new window

It should be synthesized in the implementation file:
#import "TextNoOutletAppDelegate.h"

@implementation TextNoOutletAppDelegate

@synthesize window;
@synthesize text;

// Added line to synthesize new property
@synthesize value;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
 // Insert code here to initialize your application 
}

@end

Open in new window

In Interface Builder I add the slider and one more Label.  Then I bind the slider with "value" property:
Slider control binding.I'd like to set Continuous for the slider control:
Slider control attribute modification.Now I select the new label in the prototype window and will bind it in way that is slightly different from the previous examples --  via "Value with Pattern"
Text Field. Binding via "Value with Pattern".Save my work, switch to Xcode and Build and Run my program:
Running test application

Summary:

In this article, we have seen a sort of  "simplification" of the GUI work:
We did not use Outlets of the GUI controls and
we connected more than one control to a property
This is all possible because of the nice feature of Objective-C 2.0 - Key-Value Coding or KVC.  It is a simple protocol allowing us to set and get values indirectly.

The first section of this article showed how to do the binding using Outlets.  I just used the IBOutlet keyword and then called the methods that get/set a value to/from a control.

Then, in the other examples, I specified a key that is used by Cocoa to figure out which property to match up to this key:  The property text was added to the application delegate class and key ('text') was used to bind the GUI controls with the application delegate.

References:

You can find more information about the Key-Value Coding in Objective-C 2.0 in the following articles:

1. Mac OS Reference Library. Key-Value Coding Programming Guide.

2. Mac OS X Reference Library. Cocoa Bindings Programming Topics.

3. Cocoa with Love. 5 key-value coding approaches in Cocoa

4. The Unix Geek. An Introduction to Key-Value Coding in Cocoa.
2
Comment
Author:pgnatyuk
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
0 Comments

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Join & Write a Comment

The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month