Re: Reordering a table insanity
Re: Reordering a table insanity
- Subject: Re: Reordering a table insanity
- From: Graham Cox <email@hidden>
- Date: Thu, 29 Nov 2012 11:35:52 +1100
On 29/11/2012, at 8:35 AM, Quincey Morris <email@hidden> wrote:
> On Nov 28, 2012, at 13:02 , Quincey Morris <email@hidden> wrote:
>
>> I think the loop algorithm needs to look like this:
>>
>> C1. Loop over the "less than" set starting from its highest index and working down. At each iteration, move the row at the current index to 'targetIndex - 1'. (But don't decrement targetIndex here.)
>>
>> C2. Loop over the "greater than" set starting from its lowest index and working up. At each iteration, move the row at the current index to the targetIndex row, and increment targetIndex.
>
> Ugh, I think I made the same mistake again. The decrement has to be there:
>
> C1. Loop over the "less than" set starting from its highest index and working down. At each iteration, move the row at the current index to 'targetIndex - 1' and decrement targetIndex.
>
> C2. Reset targetIndex to its original value.
>
> C3. Loop over the "greater than" set starting from its lowest index and working up. At each iteration, move the row at the current index to 'targetIndex', and increment targetIndex.
>
Yay, I think we got there :) (A night's sleep and a large infusion of caffeine has also helped with wrapping my head around this). I'm not ignoring Seth's approach either, but this seems the simpler one for the moment.
Here's my implementation, where <indexes> are the items to be moved, and <newIndexes> are where they are to end up:
NSUInteger insertionIndex = [newIndexes firstIndex] + offset;
NSUInteger moveIndex = [indexes indexLessThanIndex:insertionIndex];
while( moveIndex != NSNotFound )
{
[traceSelectorView moveRowAtIndex:moveIndex toIndex:--insertionIndex];
moveIndex = [indexes indexLessThanIndex:moveIndex];
}
insertionIndex = [newIndexes firstIndex] + offset;
moveIndex = [indexes indexGreaterThanOrEqualToIndex:insertionIndex];
while( moveIndex != NSNotFound )
{
[traceSelectorView moveRowAtIndex:moveIndex toIndex:insertionIndex++];
moveIndex = [indexes indexGreaterThanIndex:moveIndex];
}
I'm going to throw a new spanner in the works now, since in achieving this small victory (with much help and grateful thanks) I need to push the envelope a bit further...
This is factored into a method that takes two index sets, the source, and the destination. The destination starts at the insertion index and is a contiguous set having the same number of entries as the source set. Why? Because a) it allows the removal/insertion of items in the data model to be handled easily and b) it allows it to be undoable, by the simple expedient of swapping the two index sets when undoing.
The above code adds a mysterious value called 'offset', which is the amount I compensated the destination index set by to account for the items being moved that are less than the insertion index, i.e:
NSInteger offset;
offset = [indexes countOfIndexesInRange:NSMakeRange(0,insertionIndex)];
NSIndexSet* insertions = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange( insertionIndex - offset, [indexes count])]; <-- insertions becomes 'newIndexes' above when passed to that method
So the question now is, can the table reordering with animation be made to work in the undo case?
Undo works now in that the data model reordering is correctly undoable and redoable, but once again table reordering messes up, because of the assumption in the table reordering code that the insertions are contiguous. The code needs to be further generalised to move items from one arbitrary index to another.
For now I'll use my earlier implementation when undoing or redoing, which is probably acceptable.
--Graham
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden