Example code programming Objective-C with Cocoa in Xcode and Interface Builder (Leopard)

20: Two way communication between NSView and NSControl without using dummy class

Communicate out of an NSView using an IBOutlet without using a dummy Class.

Problem: (as in previous example) you want to be able to send messages from a Custom NSView to its controller and from the controller to the Custom View. The Custom View can get the Id of the Control and the Control the Id of the Custom View but you can' have each class have an include of the other classes header file (because of circularity).

Solution: (suggested by a member of the Cocoa Dev list) include a header in the Custom NSView's .m file.

This is so simple. Insufficient knowledge is a nuiscance. Even so, knowing about the using a dummy class could be handy sometime.

Implementation.

Create a new project in XCode: File->New Project->Cocoa Application
Call it: 019-NSControl-NSView

Now create the classes: MyControl of type NSObject and MyCustomView of type NSView.
Code these as shown below and save.

// MyControl.h // "020-NSControl-NSView-At-Class // #import <Cocoa/Cocoa.h> #import "MyCustomView.h" @interface MyControl : NSObject { IBOutlet MyCustomView *myCustomViewObjOutlet; IBOutlet NSTextField *myTextFieldOutlet; NSString *myControlString; } - (IBAction)assignTextFieldToCVS:(id)pId; // CVS = CustomViewString - (IBAction)showCVSInTextField:(id)pId; - (NSString *)returnNTextField; - (void)assignStringToTextField:(NSString *)pString; @end // MyControl.m // "020-NSControl-NSView-At-Class // #import "MyControl.h" @implementation MyControl - (IBAction)assignTextFieldToCVS:(id)pId; // CVS = CustomViewString { [myCustomViewObjOutlet setMyString:[myTextFieldOutlet stringValue]]; } // end assignTextFieldToCVS - (IBAction)showCVSInTextField:(id)pId; { NSString * zString = [myCustomViewObjOutlet myString]; [myTextFieldOutlet setStringValue:zString]; } // end readCustViewString - (NSString *)returnNTextField; { NSString * zString = [myTextFieldOutlet stringValue]; return zString; } // end returnNTextField - (void)assignStringToTextField:(NSString *)pString { [myTextFieldOutlet setStringValue:pString]; } // end assignStringToTextField @end // MyCustomView.h // "020-NSControl-NSView-At-Class // #import <Cocoa/Cocoa.h> #import "MyNSObject.h" // Note: one can do without the dummy class MyDummyControl but // a) this makes the fact that we are using an unconventional mechanism explicit // b) it prevents compiler warnings. // @interface MyCustomView : NSView { IBOutlet id myControlObj; // IBOutlet MyControl * myControlObj; NSString *myString; } -(NSString *)myString; -(void)setMyString:(NSString *)pString; @end // MyCustomView.m // "020-NSControl-NSView-At-Class // #import "MyCustomView.h" @implementation MyCustomView - (id)initWithFrame:(NSRect)frame { if ((self = [super initWithFrame:frame]) == nil) { NSLog(@"MyCustomView initWithFrame failed"); return self; } // end if myString = @"Hi from CustomView"; return self; } // end initWithFrame -(void)mouseUp:(NSEvent *)pTheEvent { // Note: in the past one needed to use coersion // myString = [(MyDummyControl *)myControlObj myNSTextFieldString]; //[(MyDummyControl *)myControlObj assignNSTextFieldString:@"mouseUp"]; [self setMyString: [myControlObj returnNTextField]]; [myControlObj assignStringToTextField:@"Thank you from mouseUp"]; } // end mouseUp -(NSString *)myString; { return myString; } // end myString -(void)setMyString:(NSString *)pString; { // prevent an NSInvalidArgumentException if pString is nil. if(pString) { myString = [[NSString alloc]initWithString: pString]; } else { myString = @""; } // end if } // end setMyString - (void)drawRect:(NSRect)pNSRect { [[NSColor yellowColor] set]; NSRectFill( pNSRect ); } // end drawRect @end

Bring up Interface Builder by double clicking on MainMenu.nib.

Drag a Custom NSView, two NSButtons, an NSTextField and a label onto the window and name them as shown.

XCode,Interface Builder - Do the layout

Interface Builder: Do the layout

Drag an NSObject onto the MainMenu.xib panel.
Select it and set its class to MyControl.
Note the IBAction and IBOutlets.

XCode,Interface Builder - Set class of NSObject

Interface Builder: Set class of NSObject to MyControl

Link them as shown.

XCode,Interface Builder,Link MyControl to MyCustomView

Link MyContol IBActions and IBOutlets to their targets, especially note the link to to MyCustomView

Select MyCustomView and link its IBOutlet to MyControl.

XCode,Interface Builder, Link IBOutlet of Custom NSView to MyControl

Link IBOutlet of Custom NSView to MyControl

Save and Run.

XCode,Interface Builder, Run

Run: clicking the Custom View causes it first to call the controller to return textField data and second, to call the controller to put data in the textField. The buttons generate calls from the controller to the CustomView routines

If you want to download the code

Click the Download Link to obtain 020-NSControl-NSView-At-Class.zip file of this whole OS X 10.5 Leopard program.

Download 020-NSControl-NSView-At-Class.zip (2.3 MB)

Useful Links



Please send me your comments

If you include your e-mail I may reply!  

Page last modified: 18:58 Sunday 12th. May 2013

Julius Guzy

Paintings & Drawings

  • Link to picture using new technique to represent looking through branches of a weeping willow by a river

animatedPaint