2

I have two NSTableViews on screen; I just want to drag a row from one table to the other table. I see lots of tips here and there but I do not see a complete example and I'm a bit confused. I saw examples that were totally different to Apples sample apps TableView playground and drag and drop outlineView.

I decided to use Apples method, but now im stuck. TableView playground implement these methods in their model object.

- (NSArray *)writableTypesForPasteboard:(NSPasteboard *)pasteboard
- (id)pasteboardPropertyListForType:(NSString *)type
- (NSPasteboardWritingOptions)writingOptionsForType:(NSString *)type pasteboard:(NSPasteboard *)pasteboard

I dont understand how to set these up. For the 1st method i returned an array with string @"com.mycompany.myapp.mypasteboardtype"as suggested in this question.

What should i put for the 2nd method? My model is a custom object that has a number of strings, Arrays, and dictionary variables. I also do not understand the 3rd method. I wish there was some example i could see that does a simple drag from one table to another with a custom model object.

EDIT: My implementation based on response below

-(id)pasteboardPropertyListForType:(NSString *)type {
    return [NSKeyedArchiver archivedDataWithRootObject:self];
}

-(NSArray *)writableTypesForPasteboard:(NSPasteboard *)pasteboard {
    return [NSArray arrayWithObject:myDragType];
}
// Other methods that need to be implemented

-(id)initWithPasteboardPropertyList:(id)propertyList ofType:(NSString *)type {
    return [NSKeyedUnarchiver unarchiveObjectWithData:propertyList];
}

+(NSArray *)readableTypesForPasteboard:(NSPasteboard *)pasteboard {
    return  [NSArray arrayWithObject:myDragType];
}

// And finally your object needs comply with NSCoder protocol.  These following 2 methods needs to go in the object model associated with a row.
-(void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:oneOfMyIvarsToEncode forKey:@"someKey"];
}

-(id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    if (self) {
        oneOfMyEndodedIvars = [aDecoder decodeObjectForKey:@"someKey"];
    }

    return self;
}
Community
  • 1
  • 1
Just a coder
  • 15,480
  • 16
  • 85
  • 138

1 Answers1

2

What should i put for [pasteboardPropertyListForType:]? My model is a custom object that has a number of strings, Arrays, and dictionary variables.

It depends on what type you're being asked for.

If it's your own custom type that you made up, you can put whatever you want. Really—if it's your type that you've invented, you can return whatever you want here, as long as it's a valid property list. You just have to make sure that your paste/drop code (pasteboard reading) is expecting the same stuff.

If you want to support internal drags (reordering and/or relocation within the hierarchy), you should have at least one custom type that identifies the object so that you can look up the same object when accepting the drop (in order to move it rather than duplicate it). For a Core Data object, you might use the absolute string of the object's identifying URI.

If you want to support dragging to other applications, you should have at least one non-custom type that those other applications will recognize. What type(s) you support will depend on what your model represents: if they're images (or recipes for creating them, such as stacks of layers), you could support PNG, TIFF, JPEG, etc.; if they're contacts, you could support vCard; if they're text, you could support plain text and/or RTF and/or HTML and/or WebArchive and/or Microsoft Word; etc.

You return an array of the types that this object can be turned into from writableTypesForPasteboard:; afterward, pasteboardPropertyListForType: must look at what type it was asked for and return a property list of that type.

For most external formats, pasteboardPropertyListForType: must return a data object. For your own custom formats, it's usually either a dictionary or an array of dictionaries, although, as I said, the only real requirements are that it must be a plist of some sort and your reading code must be able to understand it.

I also do not understand [writingOptionsForType:pasteboard:].

You must return a bit mask indicating when and how you will write the type to the pasteboard. The available options are documented.

Currently, there's only one: You can promise the data. This means that the pasteboard will not immediately ask you for the data; it will wait until the user pastes or drops it somewhere (or the data is otherwise requested by any application—e.g., a poorly-written drop validation method could request the data and examine it during validation, rather than drop acceptance). Only then will it call pasteboardPropertyListForType: for that type. (And this is a per-type option; you can choose to promise some types but not others.)

Promising is great for data that is expensive to compute and/or store; for example, a compressed archive (compute) or a large image (store).

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
  • Ok. one final followup question, concerning `pasteboardPropertyListForType:`, you said i can return any type so long as its a property list. In the examples TableViewPlaygorund, they returned `self`. If i try to return any other object other than self, i get a warning @"Incompatible pointer types..", would this cause any problems? – Just a coder Jul 31 '13 at 22:30
  • @Jai: Which class in that sample are you looking at? – Peter Hosey Aug 01 '13 at 04:13
  • Never mind. Seems i solved it. I'll mark this answer as correct as i have gotten the info this answer plus from another question you have answered before ----> http://stackoverflow.com/questions/7243668/nspasteboard-and-simple-custom-data – Just a coder Aug 01 '13 at 05:17
  • My confusion was because i did not know there was a Old way, and a new way. Thanks man. – Just a coder Aug 01 '13 at 05:19