PDA

View Full Version : Drag and drop in table view using core data




Monaj
May 6, 2011, 08:02 AM
Hi all,
I have made an application in which I am using core-data, array-
controllers to show data in two tables, such that -

table1 => entity: table1Entity (attributes: detail)
table2 => table2Entity (from, to, detail)

Now I am trying to perform drag from table1 and drop on table2, such
that an entity added to array controller of table2 contains value of
attribute - 'detail' from table1Entity, which is dropped.

I know that we can add an entity to an array controller subclass in
following way-

NSManagedObjectContext *mangagedObjectContext = [self
managedObjectContext];
NSString *entityName = [self entityName];
NSManagedObjectModel *managedObjectModel = [[mangagedObjectContext
persistentStoreCoordinator] managedObjectModel];
NSEntityDescription *entity = [[managedObjectModel entitiesByName]
objectForKey:entityName];
id newObject = [[NSManagedObject alloc] initWithEntity:entity
insertIntoManagedObjectContext:mangagedObjectContext];
[self addObject:newObject];

But

I am not getting, how can we extract information from dropped
object(NSManagedObject) and modify the entity(NSEntityDescription)
using it.

Can anyone suggest me how to do it?

Thanks,

Monaj



jiminaus
May 7, 2011, 08:21 PM
Check out the Using Drag and Drop in Table (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/TableView/Tasks/UsingDragAndDrop.html) chapter for the Table View Programming Guide.

Once you actually have the dropped object (I'll call it droppedObject), you'd only need to augment your code with:

newObject.detail = droppedObject.detail;


Note that when you have a core data object, you actually have a NSManagedObject subclass which Core Data has dynamically generated. This subclass will have declared properties implemented corresponding to the properties of the relevant entity.

Also note that an NSEntityDescription is only metadata. It's analogous to a class. You don't set property values in an NSEntityDescription. You only set property values in a NSManagedObject init'ed using the NSEntityDescription.

Finally, my advice would be to implement this first using a button. The user selects row(s) in table1 and then clicks the button. This will let you nut out the Core Data issues without the complication of the drag and drop protocols and pasteboards. Once you've got that working, try for drag'n'drop.

Monaj
May 8, 2011, 11:08 PM
Hi jiminaus,

Thanks for the reply :)

I did what you suggested :



newObject.detail = droppedObject.detail;



but it is not working for me :(

Below is the code which I am using:

- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info

row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation

{

NSPasteboard* pboard = [info draggingPasteboard];

NSData* rowData = [pboard dataForType:taskExchangeDataType];

NSIndexSet* rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:rowData];
[rowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
NSManagedObject *droppedObject = [[toDoController arrangedObjects] objectAtIndex:idx];

NSManagedObjectContext *mangagedObjectContext = [self managedObjectContext];
entityName = [self entityName];
NSManagedObjectModel *managedObjectModel = [[mangagedObjectContext persistentStoreCoordinator] managedObjectModel];
NSEntityDescription *entity = [[managedObjectModel entitiesByName] objectForKey:entityName];
NSManagedObject *newObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:mangagedObjectContext];
newObject.detail = droppedObject.detail; //error: property 'detail' not found on object of type 'NSManagedObject *'
[self addObject:newObject];

}];

return YES;
}


It is giving error on this line:

newObject.detail = droppedObject.detail; //error: property 'detail' not found on object of type 'NSManagedObject *'

I think it is giving this error because 'detail' is an attribute.

Please suggest !

Thanks,

Monaj

jiminaus
May 9, 2011, 02:23 AM
Error or warning? It's right that NSManagedObject doesn't have a detail property, so a warning like this would be expected.

Try keeping it declarad as type id like this:

id newObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:mangagedObjectContext];


BTW What class is this code from? The line entityName = [self entityName]; seems to suggest it's inside a model object. That would be rather peculiar. If it's is inside a controller, then this line is possibly wrong.