Cocoa NSView Drag and Drop tutorial

72: Drag and Drop images onto an NSView

Problem: We want to drag an image onto an NSView where it will be displayed. The image might be a file visible in the finder or an image in a browser window.

Drag and drop an image onto an NSView exaple

Example code for drag and drop of an image onto an NSView

Answer: We use Apple's drag and drop protocols as presented in an example by Jeff Disher on Cocoa Dev Central, and here condensed to their bare minimum.

Source code: we define but one class: a subclass of NSView.

// // MyNSView.h // #import <Cocoa/Cocoa.h> @interface MyNSView : NSView { NSImage * nsImageObj; } @property (assign) NSImage * nsImageObj; @end // // MyNSView.m // #import "MyNSView.h" @implementation MyNSView @synthesize nsImageObj; - (id)initWithFrame:(NSRect)frame { if (! (self = [super initWithFrame:frame] ) ) { NSLog(@"Error: MyNSView initWithFrame"); return self; } // end if self.nsImageObj = nil; [self registerForDraggedTypes: [NSArray arrayWithObjects:NSTIFFPboardType,NSFilenamesPboardType,nil]]; return self; } // end initWithFrame - (NSDragOperation)draggingEntered:(id )sender { if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) == NSDragOperationGeneric) { return NSDragOperationGeneric; } // end if // not a drag we can use return NSDragOperationNone; } // end draggingEntered - (BOOL)prepareForDragOperation:(id )sender { return YES; } // end prepareForDragOperation - (BOOL)performDragOperation:(id )sender { NSPasteboard *zPasteboard = [sender draggingPasteboard]; // define the images types we accept // NSPasteboardTypeTIFF: (used to be NSTIFFPboardType). // NSFilenamesPboardType:An array of NSString filenames NSArray *zImageTypesAry = [NSArray arrayWithObjects:NSPasteboardTypeTIFF, NSFilenamesPboardType, nil]; NSString *zDesiredType = [zPasteboard availableTypeFromArray:zImageTypesAry]; if ([zDesiredType isEqualToString:NSPasteboardTypeTIFF]) { NSData *zPasteboardData = [zPasteboard dataForType:zDesiredType]; if (zPasteboardData == nil) { NSLog(@"Error: MyNSView zPasteboardData == nil"); return NO; } // end if self.nsImageObj = [[NSImage alloc] initWithData:zPasteboardData]; [self setNeedsDisplay:YES]; return YES; } //end if if ([zDesiredType isEqualToString:NSFilenamesPboardType]) { // the pasteboard contains a list of file names //Take the first one NSArray *zFileNamesAry = [zPasteboard propertyListForType:@"NSFilenamesPboardType"]; NSString *zPath = [zFileNamesAry objectAtIndex:0]; NSImage *zNewImage = [[NSImage alloc] initWithContentsOfFile:zPath]; if (zNewImage == nil) { NSLog(@"Error: MyNSView performDragOperation zNewImage == nil"); return NO; }// end if self.nsImageObj = zNewImage; [self setNeedsDisplay:YES]; return YES; }// end if //this cant happen ??? NSLog(@"Error MyNSView performDragOperation"); return NO; } // end performDragOperation - (void)concludeDragOperation:(id )sender { [self setNeedsDisplay:YES]; } // end concludeDragOperation - (void)drawRect:(NSRect)dirtyRect { if (self.nsImageObj == nil) { [[NSColor blackColor] set]; NSRectFill( dirtyRect ); } // end if NSRect zOurBounds = [self bounds]; [super drawRect:dirtyRect]; [self.nsImageObj compositeToPoint:(zOurBounds.origin) operation:NSCompositeSourceOver]; } // end drawRect @end

Example source code

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