3

I have a NSCollectionView implemented and working fine. However, when dragging items around to re-arrange them, I'd like to accept drags only between objects.

The current behaviour is that you can drag between objects (it opens an space) but also over an object. I hope the images below speak better. Dragging an item over #2, for example, will put it before #2. I'd like to disable this and only accept drags in between.

In the images below:

  1. The original state
  2. Item #0 dragged between #1 and #2
  3. Item #0 dragged over #2 (the result is the same)

drag and drop

sidyll
  • 57,726
  • 14
  • 108
  • 151
  • Does your collection view have a delegate? – Willeke Sep 02 '15 at 22:01
  • @Willeke Yes, of course. – sidyll Sep 03 '15 at 14:30
  • Can you show your code where you drag, or something is relevant – tuledev Sep 04 '15 at 02:43
  • @anhtu Yes, but I don't know if it makes any difference. It's very generic and big implementation of standard drag-and-drop operations. I'm not really asking about how to fix something, just how to implement :-) any specific part you need to see? – sidyll Sep 04 '15 at 13:08
  • Why don't you detect it by index(indexPath.row or something similar) of cell? Or using `CGRectIntersectsRect`, just accept if it intersect with >= 2 cell in a row. Or using position of each cell to detect between, over. I think you already think about them. I just want to know the reason why don't? – tuledev Sep 04 '15 at 23:21
  • @anhtu I though about an strategy to refuse the drop in those cases, but I think the problem is in another place. If I simply don't accept the drop, It will basically stop working. I want that when dragging an item over another, the space between them opens normally and the item is not set selected. But is still approved as a drop. – sidyll Sep 04 '15 at 23:33
  • You really need to post your code. – Joshua Nozzi Sep 07 '15 at 01:53
  • @JoshuaNozzi do you understand about drag and drop implementations? If so, is there an specific part you want to see? Because as I stated above, there is no problem happening. Just regular implementation. I'm asking how to implement something else. If I post a reduced version, I doubt it would help. – sidyll Sep 07 '15 at 02:00
  • Your answer is exactly why you should've posted your code. It would've let us know exactly what was missing or wrong without requiring us to write a complete, contrived answer in hopes of catching what you might be missing or doing wrong. This very common operation could've been pointed out to you days ago. Help us help you. – Joshua Nozzi Sep 07 '15 at 12:48
  • Sorry @JoshuaNozzi , but I asked which part to see and you didn't reply in time. I won't post 300 lines of code here. Furthermore, I said that I had a complete implementation, so if one understand about collection view they automatically know that this method was implemented. And the answer was also pretty straightforward if one knows. Just adding a one line of statement in a standard method. You see that I answered without revealing any previous code. And of course this line was missing if I want to get this behavior. Thank you for your help but please be less picky with these questions. – sidyll Sep 07 '15 at 12:59
  • Two people asking you to post your code is not "picky"; it's far easier to determine and describe a solution when you post your code. See also: http://www.catb.org/esr/faqs/smart-questions.html – Joshua Nozzi Sep 07 '15 at 14:24
  • Sorry to turn up like this, but do you mind if I ask how you implemented those gaps (i.e. the ‘it opens a space’ part) in the first place? It’s something I’m struggling with [here](https://stackoverflow.com/questions/76093314/how-to-interactively-rearrange-nscollectionview-items-while-dragging-over-them), and you seem to maybe have insight I’m missing. – K Lee Apr 24 '23 at 17:55
  • @KLee I'll take a look. Unfortunately a long time has passed and I can't remember it all by heart, but I'll do my best to find this code and understand it. I hope I can help you. Once I find something, I'll let you know on your question. – sidyll Apr 25 '23 at 00:37

1 Answers1

4

So, after some more research, I found that the validadeDrop method has a parameter that describes exactly that, if the operation is over or in between. And since it is given as a reference, one can change the parameter to overwrite a certain behaviour. So, the solution is to add this check to the method:

- (NSDragOperation)
    collectionView:(NSCollectionView *)collectionView
      validateDrop:(id<NSDraggingInfo>)draggingInfo
     proposedIndex:(NSInteger *)proposedDropIndex
     dropOperation:(NSCollectionViewDropOperation *)proposedDropOperation
{
    /* ... */

    if (*proposedDropOperation == NSCollectionViewDropOn)
        *proposedDropOperation =  NSCollectionViewDropBefore;

    /* ... */
}
sidyll
  • 57,726
  • 14
  • 108
  • 151