Introduction to
Cocoa
Programming for
Mac OS X
Arthur Clemens
27 May 2008 - Amsterdam
What we are going to create
What are
we going to
make?
What will you learn?
XCode Tools
Interface Builder
Objective-C
How to open and process files:
open dialog, drag on icon, drag on app
Extending classes
Image resizing
Messaging
Saving
27 May 2008 | Introduction to Cocoa | 3
XCode Tools
http://developer.apple.com/
27 May 2008 | Introduction to Cocoa | 4
New application
27 May 2008 | Introduction to Cocoa | 5
XCode interface
27 May 2008 | Introduction to Cocoa | 6
Interface builder
27 May 2008 | Introduction to Cocoa | 7
Drag and drop the interface
27 May 2008 | Introduction to Cocoa | 8
Create AppController class
“AppController”
27 May 2008 | Introduction to Cocoa | 9
Instantiate AppController
27 May 2008 | Introduction to Cocoa | 10
Adding outlets
27 May 2008 | Introduction to Cocoa | 11
Adding actions
27 May 2008 | Introduction to Cocoa | 12
Setting properties
27 May 2008 | Introduction to Cocoa | 13
Make connections
27 May 2008 | Introduction to Cocoa | 14
Creating files
ctrl-drag
27 May 2008 | Introduction to Cocoa | 15
Availability of UI objects
AppController.m
- (id)init
{
self = [super init];
if (self) {
NSLog(@\"exportButton=%@\", exportButton);
}
returnself;
}
- (void)awakeFromNib
{
NSLog(@\"exportButton=%@\", exportButton);
}
27 May 2008 | Introduction to Cocoa | 17
Selectors: setting the size textfield
AppController.m
- (void)awakeFromNib
{
[imageSizeText setStringValue:@\"\"];
}
- (IBAction)updateSliderValue:(id)sender
{
[imageSizeText setStringValue:[sender stringValue]];
}
27 May 2008 | Introduction to Cocoa | 18
Objective-C is C with extensions
object instance:
[NSMutableArray alloc]
pointer to object:
NSMutableArray* list;
list = [NSMutableArray alloc];
initialize object:
NSMutableArray* list;
list = [NSMutableArray alloc];
[list init];
shorthand:
NSMutableArray* list = [[NSMutableArray alloc] init];
destroy:
[list release];
27 May 2008 | Introduction to Cocoa | 19
Methods
method that takes an argument:
selector =addObject:
[list addObject:foo];
multiple arguments:
[list insertObject:foo atIndex:5];
selector =insertObject:atIndex:
return values:
int x = [list count];
27 May 2008 | Introduction to Cocoa | 20
Memory management with reference counting
allocates memory and returns object with retain count of 1
-alloc
at 0 the object is deallocated and the memory freed
makes a copy of an object, and returns it with retain count of 1
-copy
retain count ++
-retain
retain count --
-release
retain count = number of references to the object
decreases the reference count of an object by 1 at some stage in the future
-autorelease
NSMutableArray* list =
[[[NSMutableArray alloc] init] autorelease];
or:
[NSNumber numberWithInt:5];
convenience constructor, see:
+ (NSNumber *)numberWithInt:(int)value
Cocoa class methods return autoreleased objects
27 May 2008 | Introduction to Cocoa | 21
Opening an image file in a dialog window
AppController.m
- (IBAction)showOpenPanel:(id)sender
{
NSOpenPanel *op = [NSOpenPanel openPanel];
[op beginSheetForDirectory:nil
file:nil
types:[NSImage imageFileTypes]
modalForWindow:[NSApp mainWindow]
modalDelegate:self
didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
contextInfo:nil];
}
- (void)openPanelDidEnd:(NSOpenPanel *)op only PNG:
returnCode:(int)returnCode [NSArray arrayWithObject:@\"png\"]
contextInfo:(void *)ci PNG and GIF:
{ [NSArray arrayWithObjects:@\"png\",@\"gif\",nil]
if (returnCode != NSOKButton) return;
NSString *path = [op filename];
}
AppController.h
... and update the NIB file
- (IBAction)showOpenPanel:(id)sender;
27 May 2008 | Introduction to Cocoa | 23
Connecting the menu in IB
27 May 2008 | Introduction to Cocoa | 24
Putting the image into the view
AppController.m
- (BOOL)importImageFromPath:(NSString*)path
{
NSImage *image = [[[NSImage alloc] initWithContentsOfFile:path] autorelease];
if (!image) return NO;
[imageView setImage:image];
return YES;
}
Update:
- (void)openPanelDidEnd:(NSOpenPanel *)op
returnCode:(int)returnCode
contextInfo:(void *)ci
{
if (returnCode != NSOKButton) return;
NSString *path = [op filename];
[self importImageFromPath:path];
[self setImageFilePath:path];
}
27 May 2008 | Introduction to Cocoa | 25
Opening the image file when dragging on app icon
Step 1: add code
AppController.m
- (BOOL)application:(NSApplication *)theApplication
openFile:(NSString *)path
{
// do a check on filetype here...
BOOL result = [self importImageFromPath:path];
if (!result) return NO;
[self setImageFilePath:path];
return YES;
}
Step 2: edit app document types...
Step 3: set the File’s Owner delegate...
27 May 2008 | Introduction to Cocoa | 26
Opening target info
Command-i
27 May 2008 | Introduction to Cocoa | 27
Set the app delegate in IB
27 May 2008 | Introduction to Cocoa | 28
Drag and drop onto the app window
We need to extend the image view.
Step 1: create a new subclass for
NSImageView: ImageView
Step 2: edit the code
@interface ImageView : NSImageView
{
}
Step 3: drag new .h file onto IB and set view to new subclass...
Step 4: add drag and drop methods...
27 May 2008 | Introduction to Cocoa | 29
Set image view to new subclass in IB
27 May 2008 | Introduction to Cocoa | 30
Drag and drop methods
ImageView.m
@implementation ImageView
#pragma mark Drag and drop
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender
{
return NSDragOperationLink;
}
- (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender
{
returnYES;
}
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
{
return YES;
}
- (void)concludeDragOperation:(id<NSDraggingInfo>)sender
{
[super concludeDragOperation:sender];
}
@end
27 May 2008 | Introduction to Cocoa | 31
Testing: loading an image from the app bundle
Drag image on XCode: Resources
AppController.m
- (void)awakeFromNib
{
[imageSizeText setStringValue:@\"\"];
NSString* path = [[NSBundle mainBundle] pathForImageResource:@\"anteprima.com.png\"];
[self importImageFromPath:path];
}
27 May 2008 | Introduction to Cocoa | 32
Show image in real size
Override NSImageView’s drawRect:
ImageView.m
- (void)drawRect:(NSRect)rect
{
if ([self image]) {
NSRect imageRect;
imageRect.origin = NSZeroPoint;
imageRect.size = [[self image] size];
NSRect drawRect = imageRect;
[[self image] drawInRect:drawRect
fromRect:imageRect
operation:NSCompositeSourceOver
fraction:1.0];
}
}
The image is now oriented bottom left.
27 May 2008 | Introduction to Cocoa | 33
Orient to top left
Flip coordinate system:
ImageView.m
- (BOOL)isFlipped
{
return YES;
}
27 May 2008 | Introduction to Cocoa | 34
Use a transformation to flip the image
Update drawRect in ImageView.m
- (void)drawRect:(NSRect)rect
{
if ([self image]) {
NSRect imageRect;
imageRect.origin = NSZeroPoint;
imageRect.size = [[self image] size];
NSAffineTransform* transform = [NSAffineTransform transform];
[transform translateXBy:0.0
yBy:1.0 * imageRect.size.height];
[transform scaleXBy:[zoomFactor floatValue]
yBy:-[zoomFactor floatValue]];
[transform concat];
NSRect drawRect = imageRect;
[[self image] drawInRect:drawRect
fromRect:imageRect
operation:NSCompositeSourceOver
fraction:1.0];
}
}
27 May 2008 | Introduction to Cocoa | 35
Connect the slider value to
the image size
Replace updateSliderValue in AppController.m
- (IBAction)updateSliderValue:(id)sender
{
[imageView setZoomFactor:[sender objectValue]];
}
Update drawRect in ImageView.m
[transform translateXBy:0.0
yBy:[zoomFactor floatValue] * imageRect.size.height];
27 May 2008 | Introduction to Cocoa | 37
Receiving the notification
Add toawakeFromNib inAppController.m
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleImageUpdated:)
name:@\"imageUpdated\"
object:nil];
Unsubscribe before AppController is destroyed:
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self setImageFilePath:nil];
[super dealloc];
}
Update the text field
- (void)handleImageUpdated:(NSNotification*)note
{
NSSize size = [[note object] sizeValue];
[imageSizeText setStringValue:[NSString stringWithFormat:@\"%.0f x %.0f\", size.width, size.height]];
}
27 May 2008 | Introduction to Cocoa | 39
Update the text field when the image is loaded
Override tosetImage inImageView.m
- (void)setImage:(NSImage *)image
{
[super setImage:image];
[self notifyImageUpdated];
}
27 May 2008 | Introduction to Cocoa | 40
Update the file path when the image is dragged
Update concludeDragOperation in ImageView.m
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
{
[super concludeDragOperation:sender];
NSPasteboard *pboard = [sender draggingPasteboard];
NSString* draggedFilePath = nil;
if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
draggedFilePath = [files objectAtIndex:0];
}
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
[[NSNotificationCenter defaultCenter] postNotificationName:@\"imageDragged\" object:draggedFilePath];
}
Register for notifications inAppController.m
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleImageDragged:)
name:@\"imageDragged\"
object:nil];
- (void)handleImageDragged:(NSNotification*)note
{
NSString* imagePath = [note object];
[self setImageFilePath:imagePath];
}
27 May 2008 | Introduction to Cocoa | 41
Export the image: Categories
Categories are the prototypes of Cocoa.
Extend a class without subclassing
PrettyPrintCategory.h
@interface NSArray (PrettyPrintElements)
- (NSString *)prettyPrintDescription;
@end
PrettyPrintCategory.m
#import \"PrettyPrintCategory.h\"
@implementation NSArray (PrettyPrintElements)
- (NSString *)prettyPrintDescription {
// implementation code here...
}
@end
Create new Cocoa class ImageViewAdditions (m and h files)
27 May 2008 | Introduction to Cocoa | 42
This tutorial walks you through the fundamentals of more
This tutorial walks you through the fundamentals of Cocoa: XCode Tools, Interface Builder, Objective-C (variables, methods and memory management), and goes on to explain useful Cocoa principles for building an Image Resizer application: how to open and process files (using both a dialog screen and drag and drop), NSImage, messaging and saving.
Get the source code at http://visiblearea.com/blog/bin/view/VisibleArea/Image_Resizer_a_Cocoa_Tutorial less
0 comments
Post a comment