lxcid / LXReorderableCollectionViewFlowLayout

Extends `UICollectionViewFlowLayout` to support reordering of cells. Similar to long press and pan on books in iBook.
http://lxcid.com/
MIT License
1.86k stars 328 forks source link

Getting the new order of items after sort. #13

Open JTylerGary opened 11 years ago

JTylerGary commented 11 years ago

I've been trying to get the resulting order after the cells have been moved.

I've used this to make an array. I've noticed the index order seems to vary and of course I get an indexPath for visible cells.

NSArray *visible = [self.collectionView indexPathsForVisibleItems]; NSMutableArray *rowsArray = [NSMutableArray arrayWithCapacity:[visible count]]; [visible enumerateObjectsUsingBlock:^(NSIndexPath *indexPath, NSUInteger idx, BOOL *stop) { [rowsArray addObject:@(indexPath.item)];

    NSLog(@"This is the indexPathsForVisibleItems as array named visible %@", visible);`

But I want to peek inside and get new order. I wish I knew how to get the image displayed in a cell by using the indexPath for the visible cells after a sort but I'm not sure how to do that.

I can get the object at a cell using something like this.

NSObject *getCell = [self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];

I get the layout object.

lxcid commented 11 years ago

There seems to be a problem accessing index path immediately after move, as documented in my comment here.

https://github.com/lxcid/LXReorderableCollectionViewFlowLayout/issues/8#issuecomment-12826498

Could you try the accompanying solution in the linked comment instead and see if it resolve your issue?

JTylerGary commented 11 years ago

I'll give it a try. I was not getting nil and I was getting an object. But the array of indexPaths seemed to stay constant. I assumed it was the operation of indexPathsForVisibleItems and that it just tells which ones are visible and not a reordering of the the indexPaths based on some sort of key or index. Sorry, what I'm trying to do seems complicated to me.

lukescott commented 11 years ago

@ALulzyApprentice When I have a chance I'll look into this and see what I can come up with. If you could try this fork and verify it's still an issue, please open an Issue there.

JTylerGary commented 11 years ago

I'm eventually went for something else. My skills are low level. But I managed to get the objects out and into another array. I then compared it to another array of those objects I collected when the view is displayed. By iterating through the array of objects after the rearrange happened I was able to figure out what has moved and to where. The little hurdle i had to deal with is not related to what Stan referred me to. Well as far as I can tell.

So I did not need to really know much about the format of the layout object that is returned. I just needed to figure out how to make a comparison of before and after states.

Luke I will def. take a look at your fork when I get a chance.

lukescott commented 11 years ago

Are you using a NSMutableArray as your data source, and then mutating it on each data source delegate call? I'm unclear as to why you need to compare anything.

Should be able to do something like this:

- (void)collectionView:(UICollectionView *)theCollectionView layout:(UICollectionViewLayout *)theLayout
itemAtIndexPath:(NSIndexPath *)theFromIndexPath willMoveToIndexPath:(NSIndexPath *)theToIndexPath {
    id theFromItem = [self.deck objectAtIndex:theFromIndexPath.item];
    [self.deck removeObjectAtIndex:theFromIndexPath.item];
    [self.deck insertObject:theFromItem atIndex:theToIndexPath.item];
}
JTylerGary commented 11 years ago

I don't have the code handy. But I have an NSMutableArray with some images named using numbers. That populates the UICollectionView. When the view is displayed it is displayed in order. I'm only using one suit, btw. I use that forst array and match it to the layout objects when it is first displayed. That goes into another array. I use this new array to compare to an array I get from using indexPathsForVisibleItems.

I tried to use code very similar to what you posted. I did not get it to work for me. The id was being switched to the new position. So if something formerly had a position of say 4 and was moved to 0, the id would change to reflect it's new position. That being id 0. I was probably doing it all wrong. But basically I needed to keep two arrays in sync. So by getting an initial state and then going through each item in the array from the final state I could produce yet another array with the new order in a form I could use. I could iterate through the initial state array and look for that object in the final state array and get it's index or position from there.

I was not mutating on each delegate call. I was doing all this when I was sure there would be now more moving of cells. I figured why do it on every move when I can just do it when the view goes away.

lukescott commented 11 years ago

Ok, I'm still not sure what you mean. The sample project included should work correctly. There should be no need to do any comparisons - If a single item moves the old one is backed up, removed, and inserted into the new index.

So if you have:

0 - A 1 - B 2 - C 3 - D 4 - E 5 - F

And if you move B below D it will give you 1 as the old position and 3 as the new position.

When you remove B the indexes are automatically decremented by the NSMutableArray:

0 - A 2 -> 1 - C 3 -> 2 - D 4 -> 3 - E 5 -> 4 - F

Then when you insert something anything below is incremented:

0 - A 1 - C 2 - D -> 3 - B 3 -> 4 - E 4 -> 5 - F

Could you be more specific what didn't work?

JTylerGary commented 11 years ago

I'm not sure what didn't work. But the method I used works. Probably not the best or most efficient way. But I got what I wanted to work, I think. I'm new to Obj-C but not new to programming. I was having problems. I think it was because of the format, the object, that was returned when I queried using 'indexPathsForVisibleItems was in a form that made my eyes glaze over. The objects were long and had much information in it. I'm just not used to UICollectionView or UITableView for that matter. I'm a newb.

Some form of Ordered array would have helped but I did not progress that far to use it effectively and the net did not provide me with enough good examples. Oh well.