Moving items from one tableView to another tableView with extra's

Posted by Totumus Maximus on Stack Overflow See other posts from Stack Overflow or by Totumus Maximus
Published on 2011-11-25T10:31:52Z Indexed on 2011/11/28 9:52 UTC
Read the original article Hit count: 535

Let's say I have 2 UITableViews next to eachother on an ipad in landscape-mode. Now I want to move multiple items from one tableView to the other. They are allowed to be inserted on the bottom of the other tableView. Both have multiSelection activated.

Now the movement itself is no problem with normal cells. But in my program each cell has an object which contains the consolidationState of the cell. There are 4 states a cell can have: Basic, Holding, Parent, Child. Basic = an ordinary cell. Holding = a cell which contains multiple childs but which wont be shown in this state. Parent = a cell which contains multiple childs and are shown directly below this cell. Child = a cell created by the Parent cell.

The object in each cell also has some array which contains its children. The object also holds a quantityValue, which is displayed on the cell itself.

Now the movement gets tricky. Holding and Parent cells can't move at all. Basic cells can move freely. Child cells can move freely but based on how many Child cells are left in the Parent. The parent will change or be deleted all together. If a Parent cell has more then 1 Child cell left it will stay a Parent cell. Else the Parent has no or 1 Child cell left and is useless. It will then be deleted.

The items that are moved will always be of the same state. They will all be Basic cells.

This is how I programmed the movement:

*First I determine which of the tableViews is the sender and which is the receiver.

*Second I ask all indexPathsForSelectedRows and sort them from highest row to lowest.

*Then I build the data to be transferred. This I do by looping through the selectedRows and ask their object from the sender's listOfItems.

*When I saved all the data I need I delete all the items from the sender TableView. This is why I sorted the selectedRows so I can start at the highest indexPath.row and delete without screwing up the other indexPaths.

  • *When I loop through the selectedRows I check whether I found a cell with state Basic or Child.

  • *If its a Basic cell I do nothing and just delete the cell. (this works fine with all Basic Cells)

  • *If its a Child cell I go and check it's Parent cell immidiately. Since all Child cells are directly below the Parent cell and no other the the Parent's Childs are below that Parent I can safely get the path of the selected Childcell and move upwards and find it's Parent cell. When this Parent cell is found (this will always happen, no exceptions) it has to change accordingly.

    • *The Parent cell will either be deleted or the object inside will have its quantity and children reduced.
  • *After the Parent cell has changed accordingly the Child cell is deleted similarly like the Basic cells

*After the deletion of the cells the receiver tableView will build new indexPaths so the movedObjects will have a place to go.

*I then insert the objects into the listOfItems of the receiver TableView.

The code works in the following ways: Only Basic cells are moved. Basic cells and just 1 child for each parent is moved. A single Basic/Child cell is moved.

The code doesn't work when: I select more then 1 or all childs of some parent cell.

The problem happens somewhere into updating the parent cells. I'm staring blindly at the code now so maybe a fresh look will help fix things. Any help will be appreciated.

Here is the method that should do the movement:

-(void)moveSelectedItems
{ 
    UITableView *senderTableView = //retrieves the table with the data here.
    UITableView *receiverTableView = //retrieves the table which gets the data here.

    NSArray *selectedRows = senderTableView.indexPathsForSelectedRows;

    //sort selected rows from lowest indexPath.row to highest
    selectedRows = [selectedRows sortedArrayUsingSelector:@selector(compare:)];

    //build up target rows (all objects to be moved)
    NSMutableArray *targetRows = [[NSMutableArray alloc] init];
    for (int i = 0; i<selectedRows.count; i++) 
    {
        NSIndexPath *path = [selectedRows objectAtIndex:i];
        [targetRows addObject:[senderTableView.listOfItems objectAtIndex:path.row]];
    }

    //delete rows at active
    for (int i = selectedRows.count-1; i >= 0; i--) 
    {
        NSIndexPath *path = [selectedRows objectAtIndex:i];

        //check what item you are deleting. act upon the status. Parent- and HoldingCells cant be selected so only check for basic and childs
        MyCellObject *item = [senderTableView.listOfItems objectAtIndex:path.row];
        if (item.consolidatedState == ConsolidationTypeChild) 
        {
            for (int j = path.row; j >= 0; j--) 
            {
                MyCellObject *consolidatedItem = [senderTableView.listOfItems objectAtIndex:j];
                if (consolidatedItem.consolidatedState == ConsolidationTypeParent) 
                {
                    //copy the consolidated item but with 1 less quantity
                    MyCellObject *newItem = [consolidatedItem copyWithOneLessQuantity]; //creates a copy of the object with 1 less quantity.

                    if (newItem.quantity > 1)
                    {
                        newItem.consolidatedState = ConsolidationTypeParent;
                        [senderTableView.listOfItems replaceObjectAtIndex:j withObject:newItem];
                    }
                    else if (newItem.quantity == 1)
                    {
                        newItem.consolidatedState = ConsolidationTypeBasic;
                        [senderTableView.listOfItems removeObjectAtIndex:j];

                        MyCellObject *child = [senderTableView.listOfItems objectAtIndex:j+1];

                        child.consolidatedState = ConsolidationTypeBasic;

                        [senderTableView.listOfItems replaceObjectAtIndex:j+1 withObject:child];
                    }
                    else 
                    {
                        [senderTableView.listOfItems removeObject:consolidatedItem];
                    }
                    [senderTableView reloadData];
                }
            }
        }
        [senderTableView.listOfItems removeObjectAtIndex:path.row];
    }
    [senderTableView deleteRowsAtIndexPaths:selectedRows withRowAnimation:UITableViewRowAnimationTop];

    //make new indexpaths for row animation
    NSMutableArray *newRows = [[NSMutableArray alloc] init];
    for (int i = 0; i < targetRows.count; i++) 
    {
        NSIndexPath *newPath = [NSIndexPath indexPathForRow:i+receiverTableView.listOfItems.count inSection:0];
        [newRows addObject:newPath];
        DLog(@"%i", i);

        //scroll to newest items
        [receiverTableView setContentOffset:CGPointMake(0, fmaxf(receiverTableView.contentSize.height - recieverTableView.frame.size.height, 0.0)) animated:YES];
    }

    //add rows at target
    for (int i = 0; i < targetRows.count; i++) 
    {
        MyCellObject *insertedItem = [targetRows objectAtIndex:i];

        //all moved items will be brought into the standard (basic) consolidationType
        insertedItem.consolidatedState = ConsolidationTypeBasic;

        [receiverTableView.ListOfItems insertObject:insertedItem atIndex:receiverTableView.ListOfItems.count];
    }

    [receiverTableView insertRowsAtIndexPaths:newRows withRowAnimation:UITableViewRowAnimationNone];
}

If anyone has some fresh ideas of why the movement is bugging out let me know. If you feel like you need some extra information I'll be happy to add it. Again the problem is in the movement of ChildCells and updating the ParentCells properly.

I could use some fresh looks and outsider ideas on this.

Thanks in advance.


*updated based on comments

© Stack Overflow or respective owner

Related posts about objective-c

Related posts about iPad