apptekstudios / ASCollectionView

A SwiftUI collection view with support for custom layouts, preloading, and more.
MIT License
1.36k stars 160 forks source link

ASDragDropConfig enableReordering shouldMoveItem closure #161

Closed adamtow closed 3 years ago

adamtow commented 4 years ago

How does the shouldMoveItem closure in ASDragDropConfig enableReordering actually work? I tried modifying the PhotoGrid sample with the attached code. I never see the reorderData function call, let alone the print statement.

I don't see where the shouldMoveItem closure is being called in ASCollectionView.

var dragDropConfig: ASDragDropConfig<Post> {
    ASDragDropConfig<Post>(dataBinding: $data)
        .enableReordering(shouldMoveItem: self.reorderData)
        .dragItemProvider { item in
            NSItemProvider(object: item.url as NSURL)
        }
}

func reorderData(_ sourceIndexPath: IndexPath, _ destinationIndexPath: IndexPath) -> Bool {
    let itemToMove = self.data.remove(at: sourceIndexPath.row)
    print("Trying to move: \(itemToMove)")
    self.data.insert(itemToMove, at: destinationIndexPath.row)  
    return true
}
donly commented 4 years ago

Yes, I have the same question here

apptekstudios commented 4 years ago

It appears that I added this closure to the API but forgot to remove it when I didn't get time to implement it, sorry for that! Would welcome a PR if anyone gets a chance.

The reordering functionality that is built in acts automatically via the binding passed to ASDragDropConfig. This extra closure was intended as a chance to prevent some items in the section from being moved (by returning false). I imagine that under-the-hood it could be queried during the UIKit itemsForBeginning session: UIDragSession and performDropWith coordinator functions.

apptekstudios commented 4 years ago

V1.8.0 (WIP) has now implemented a canMoveItem closure that is called to check whether to apply a move. image

It also includes a way to manually apply drag/drop to your data, without using the data binding image

adamtow commented 4 years ago

Could you add another modifier called "canDropItem" which sets the value of the dropEnabled variable in the ASDragDropConfig?

The use case that I'm thinking is dropping an item from outside the app onto the ASCollectionView. If it's a particular type, the drop should be passed from the collection view to the children in the collection view. Right now, I can do this only if I set dropEnabled and reorderingEnabled to false in ASDragDropConfig, which disables drag and drop reordering.

apptekstudios commented 4 years ago

@adamtow re: canDropItem... I couldn't find a way to achieve this sadly. SwiftUI is greedy and steals all drop requests (regardless of whether it has a view accepting a drop, and regardless of what portion of the cell it takes up). Therefore to get collectionView drag/drop to work at all we need to disable SwiftUI's drop handler. I haven't had a chance but this is probably worthy of a radar.