Cocoa Programming for Mac OS X - Aaron Hillegass [92]
Note that UTIs are not used directly in any of the preceding methods. Instead, they are class focused.
NSPasteboardItem, which itself conforms to NSPasteboardReading and NSPasteboardWriting, allows you to work much more closely with the pasteboard contents using UTIs. Here are some of the more commonly used methods on NSPasteboardItem:
- (BOOL)setDataProvider:(id Used for providing pasteboard data lazily, declares that provider will provide the given types when requested. Here are a few of the global variables for the standard types. Each of these evaluates to a UTI. NSPasteboardTypeColor NSPasteboardTypeFont NSPasteboardTypePDF NSPasteboardTypeRuler NSPasteboardTypeRTF NSPasteboardTypeRTFD NSPasteboardTypeHTML NSPasteboardTypeString NSPasteboardTypeTabularText NSPasteboardTypeTIFF kUTTypeURL You can also create your own UTIs for use with the pasteboard. - (BOOL)setData:(NSData *)aData forType:(NSString *)dataType - (BOOL)setString:(NSString *)s forType:(NSString *)dataType - (BOOL)setPropertyList:(id)plist forType:(NSString *)dataType Write data to the pasteboard. - (NSArray *)types Returns an array containing the types of data that are available to be read from the pasteboard. - (NSString *)availableTypeFromArray:(NSArray *)types Returns the first type found in types that is available for reading from the pasteboard; types should be a list of all types that you would be able to read. - (NSData *)dataForType:(NSString *)dataType - (NSString *)stringForType:(NSString *)dataType - (id)propertyListForType:(nSString *)dataType Read data from the pasteboard. Add Cut, Copy, and Paste to BigLetterView - (void)writeToPasteboard:(NSPasteboard *)pb { // Copy data to the pasteboard [pb clearContents]; [pb writeObjects:[NSArray arrayWithObject:string]]; } - (BOOL)readFromPasteboard:(NSPasteboard *)pb { NSArray *classes = [NSArray arrayWithObject:[NSString class]]; NSArray *objects = [pb readObjectsForClasses:classes options:nil]; if ([objects count] > 0) { // Read the string from the pasteboard NSString *value = [objects objectAtIndex:0]; // Our view can handle only one letter if ([value length] == 1) { [self setString:value]; return YES; } } return NO; } Note how we have implemented the write and read methods. When writing to the pasteboard, we clear its contents and then write objects to it. When reading from the pasteboard, we supply an array of the classes we are interested in and then request the matching objects from the pasteboard. By implementing the NSPasteboardWriting and NSPasteboardReading protocols, the NSString class has made this task very simple. Declare the cut:, copy:, and paste: methods in BigLetterView.h: - (IBAction)cut:(id)sender; - (IBAction)copy:(id)sender; - (IBAction)paste:(id)sender; Implement these methods in BigLetterView.m: - (IBAction)cut:(id)sender { [self copy:sender]; [self setString:@""]; } - (IBAction)copy:(id)sender { NSPasteboard *pb = [NSPasteboard generalPasteboard]; [self writeToPasteboard:pb]; } - (IBAction)paste:(id)sender { NSPasteboard *pb = [NSPasteboard generalPasteboard]; if(![self readFromPasteboard:pb]) { NSBeep(); } } Build and run the application. Note that the Cut, Copy, and Paste menu items now work when the BigLetterView is selected. The keyboard equivalents also work. You can copy only strings that have one character into the BigLetterView. Nil-Targeted Actions
You will create methods named cut:, copy:, and paste: in the BigLetterView class. To make these methods easier to write, you will first create methods for putting data onto and reading data off a pasteboard. Add these methods to BigLetterView.m:
How is the right view sent the cut:, copy:, or paste: message? After all, there are many, many views. If you select a text field, it should get the message. When you select another view and then choose the Copy or Paste