Matt
Matt

Reputation: 448

Reordering NSCollectionView with (Flow Layout)

I have a NSCollectionView, which I want to reorder. I´m using a Flow Layout, Delegate and Datasource is set to my ViewController. I have also registered my drag type but I only get the delegate call for:

- (BOOL)collectionView:(NSCollectionView *)collectionView canDragItemsAtIndexes:(NSIndexSet *)indexes withEvent:(NSEvent *)event;

But not for the other delegate calls. Here is my ViewController source code:

#import "ViewController.h"
#import "CollectionViewItem.h"

@interface ViewController ()

@property(nonatomic, strong) NSArray *strings;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do view setup here.
}


- (void)awakeFromNib
{
    self.strings = @[@"a", @"b", @"c", @"d", @"e", @"f", @"g", @"h"];

    NSArray *supportedTypes = [NSArray arrayWithObjects:@"CustomDDType", nil];
    [self.collectionView registerForDraggedTypes:supportedTypes];
}


#pragma mark CollectionView DataSource


- (NSInteger) numberOfSectionsInCollectionView:(NSCollectionView *)collectionView
{
    return 1;
}


- (NSInteger) collectionView:(NSCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return self.strings.count;
}



- (NSCollectionViewItem * ) collectionView:(NSCollectionView *)collectionView itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath
{
    CollectionViewItem *item = [collectionView makeItemWithIdentifier:@"CollectionViewItem" forIndexPath:indexPath];
    item.myTitle.stringValue = [self.strings objectAtIndex:indexPath.item];

    return item;
}

#pragma mark Drag/Drop

- (BOOL)collectionView:(NSCollectionView *)collectionView canDragItemsAtIndexes:(NSIndexSet *)indexes withEvent:(NSEvent *)event {
    NSLog(@"canDragItems");
    return YES;
}


-(NSDragOperation)collectionView:(NSCollectionView *)collectionView validateDrop:(id<NSDraggingInfo>)draggingInfo proposedIndex:(NSInteger *)proposedDropIndex dropOperation:(NSCollectionViewDropOperation *)proposedDropOperation {
    NSLog(@"Validate Drop");
    return NSDragOperationMove;
}


-(BOOL)collectionView:(NSCollectionView *)collectionView writeItemsAtIndexes:(NSIndexSet *)indexes toPasteboard:(NSPasteboard *)pasteboard
{
    NSLog(@"Write Items at indexes : %@", indexes);

    NSData *indexData = [NSKeyedArchiver archivedDataWithRootObject:indexes];
    [pasteboard declareTypes:@[@"CustomDDType"] owner:self];
    [pasteboard setData:indexData forType:@"CustomDDType"];

    return YES;
}


- (BOOL)collectionView:(NSCollectionView *)collectionView acceptDrop:(id<NSDraggingInfo>)draggingInfo index:(NSInteger)index dropOperation:(NSCollectionViewDropOperation)dropOperation {
    NSLog(@"Accept Drop");

    NSPasteboard *pBoard = [draggingInfo draggingPasteboard];
    NSData *indexData = [pBoard dataForType:@"CustomDDType"];
    NSIndexSet *indexes = [NSKeyedUnarchiver unarchiveObjectWithData:indexData];
    NSInteger draggedCell = [indexes firstIndex];

    return YES;
}

@end

Did I miss something? I cannot use the new delegate calls, introduced in 10.11, because my project needs to run before.

Upvotes: 0

Views: 805

Answers (1)

Andrew Riznyk
Andrew Riznyk

Reputation: 61

OK!!! So you are re-Ordering a flow layout! This can be tricky - I am not on my Mac so i will give you the 'Overview'

When reordering any Table / Collection and you have multiple changes, you need to batch update to datasource. (you may already know that)

Make sure to connect your datasource and delegate to the view. (i dont see it in code so i suppose you did it in interface builder)

Lastly you may want to check that your collection view is Strong (So strong) - because it may be losing its reference before it ever displays. - If none of this works let me know.

Upvotes: 0

Related Questions