Objective-C and Delegates

Published March 25, 2011
Advertisement
So I had a chance to sit down and do a challenge from my Objective-C book today. The challenge was to create a delegate to the Window object to control resizing so that the window is always twice as wide as it is tall.

For people who don't know in Objective-C a delegate is a way to reroute method calls from one object to another object for handling. This is more flexible then delegates in C# because those delegates are technically listeners where delegates in Objective-C are protocols that must be conformed to. A protocol in Objective-C is similar to an interface in C# where it is a strict set of guidelines that must be followed however Objective-C allows you to omit implementation of certain aspects allowing for you to decide what you want to handle. The nice thing about delegates is it allows for the modification of the behavior of an object without your delegate needing to know about the object it is modifying the behavior of. This basically means it removes the need of obsessive subclassing which is a good thing.

So onto the implementation of this challenge. In order to modify the sizing control of a Window object we need to delegate the windowWillResize message to our handler class.

For this we will create a simple handler class we will just call WindowDelegate for simplicity.




[size=1]WindowDelegate.h:
[size=1]

[size=1]#import
@interface WindowDelegate : NSObject {


[size=1]}
[size=1]

[size=1]@end


[size=1]

[size=1]This code is very simple basically all we do is tell our WindowDelegate class to conform to the NSWindowDelegate protocol which contains our windowWillResize message.
[size=1]

[size=1]So now we need to implement the windowWillResize message so that it will keep our window twice as wide as it is tall.
[size=1]To do this we need to know the signature of the windowWillResize message the signature is...
[size=1]- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize;
[size=1]

[size=1]Basically this message brings in a pointer to the calling object and a new size for the calling object and we return the size back to the calling object.
[size=1]

[size=1]Now the implementation.
[size=1]

[size=1]WindowDelegate.m:
[size=1]#import "WindowDelegate.h"
@implementation WindowDelegate
- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize {

[size=1] float newWidth = frameSize.width;
[size=1] float newHeight = frameSize.height;
[size=1]

[size=1] if ((newWidth/newHeight) != newHeight) {
[size=1] NSLog(@"Width is not equal to twice height modifying width.");
[size=1] NSSize newSize;
[size=1] newSize.width = newHeight * 2;
[size=1] newSize.height = newHeight;
[size=1] NSLog(@"New window size: %f x %f", newSize.width, newSize.height);
[size=1] return newSize;
[size=1] }
[size=1]

[size=1] NSLog(@"New window size: %f x %f", frameSize.width, frameSize.height);
[size=1] return frameSize;
[size=1]

[size=1]@end
[size=1]

[size=1]NSSize is a C struct that contains the width and the height of the object. so we don't need to use it as a pointer.
[size=1]We don't need to declare the method in the header because the Protocol declares the method and we basically insert it into our class at compile time. We also don't even need to instantiate the class at all in code. This is one of my favorite things about Objective-C and Cocoa. To use this delegate you open up Interface Builder and add the Object to your application and then simply connect the windows delegate property to your object in interface builder. When the nib file is serialized into memory the Objective-C runtime will automatically instantiate the delegate class for us.
[size=1]

[size=1]That is all for today. Again I apologize for the screwed up code tags I am not sure if it is IPB or Safari at this moment that is screwing them up. Either way I hope it is fixed soon.
0 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement