Objective c 通过合并将项目从一个表视图移动到另一个表视图

Objective c 通过合并将项目从一个表视图移动到另一个表视图,objective-c,uitableview,ipad,Objective C,Uitableview,Ipad,假设我在ipad上以横向模式拥有两个相邻的UITableView。 现在我想将多个项目从一个tableView移动到另一个tableView。它们可以插入到另一个tableView的底部。两者都已激活 现在,正常细胞的运动本身没有问题。但是在我的程序中,每个单元格都有一个包含单元格合并状态的对象。一个单元格可以有4种状态:基本状态、保留状态、父状态、子状态。 基本=普通单元格。 Holding=包含多个子项但在此状态下不会显示的单元格。 父项=包含多个子项且直接显示在此单元格下方的单元格。 子单

假设我在ipad上以横向模式拥有两个相邻的UITableView。 现在我想将多个项目从一个tableView移动到另一个tableView。它们可以插入到另一个tableView的底部。两者都已激活

现在,正常细胞的运动本身没有问题。但是在我的程序中,每个单元格都有一个包含单元格合并状态的对象。一个单元格可以有4种状态:基本状态、保留状态、父状态、子状态。 基本=普通单元格。 Holding=包含多个子项但在此状态下不会显示的单元格。 父项=包含多个子项且直接显示在此单元格下方的单元格。 子单元=父单元创建的单元

每个单元格中的对象也有一些包含其子对象的数组。该对象还保存quantityValue,该值显示在单元格本身上

现在,运动变得棘手。保留单元格和父单元格根本无法移动。基本细胞可以自由移动。子单元可以自由移动,但取决于父单元中剩余的子单元数量。父项将一起更改或删除。 如果父单元格剩余的子单元格超过1个,则它将保持为父单元格。 否则,父单元格没有或只剩下一个子单元格,因此无效。然后它将被删除

移动的项目将始终处于相同的状态。它们都是基本细胞

这就是我如何编程的运动:

-(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];
}
*首先,我确定哪些TableView是发送方,哪些是接收方

*其次,我询问所有indexPathsForSelectedRows,并将它们从最高行排序到最低行

*然后我构建要传输的数据。我通过循环遍历selectedRows并从发件人的列表项中询问他们的对象来实现这一点

*当我保存所有需要的数据时,我会从sender表视图中删除所有项目。这就是为什么我对selectedRows进行了排序,这样我就可以从最高的indexPath.row开始删除,而不会弄乱其他indexPath

  • *当我在选定的行中循环时,我会检查是否找到状态为Basic或Child的单元格

  • *如果它是一个基本单元,我什么也不做,只是删除该单元。(这适用于所有基本单元格)

  • *如果它是一个子细胞,我马上去检查它的父细胞。由于所有子单元格都直接位于父单元格下方,并且没有其他父单元格的子单元格位于该父单元格下方,因此我可以安全地获取所选子单元格的路径并向上移动并找到其父单元格。当找到父单元格时(这种情况总是会发生,没有例外),它必须相应地更改

    • *父单元格将被删除,或者其中的对象将减少其数量和子单元格
  • *父单元格相应更改后,子单元格将像基本单元格一样删除

*删除单元格后,receiver tableView将构建新的索引路径,以便movedObjects有地方可去

*然后,我将这些对象插入receiver TableView的ListoItems中

该代码以以下方式工作: 只移动基本单元格。 移动基本单元格,每个父项只移动一个子项。 移动单个基本/子单元格

以下情况下,代码不起作用: 我选择多个父单元格的1个或所有子单元格

问题发生在更新父单元格的某个地方。我现在盲目地盯着代码看,所以也许重新审视一下会有助于解决问题。任何帮助都将不胜感激

以下是进行移动的方法:

-(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];
}

更新:事实上这段代码有很多问题。从主数组中删除父行后,selectedRows数组的NSINDExpath中存储的值基本上已过时

以下是经过测试和运行的代码(使用OP后)

for(int i=selectedRows.count-1;i>=0;i--)
{
nsindepath*path=[selectedRows objectAtIndex:i];
//检查要删除的项目。根据状态进行操作。无法选择父单元格和保留单元格,因此将只对子单元格和基本单元格进行检查
mycelobject*item=[sender.listOfItems objectAtIndex:path.row];
if(item.consolidatedState==ConsolidationTypeChild)
{
对于(int j=path.row;j>=0;j--)
{
mycelobject*consolidatedItem=[sender.listOfItems objectAtIndex:j];
if(consolidatedItem.consolidatedState==ConsolidationTypeParent)
{
//复制合并项目,但数量减少1
MyCellObject*newItem=[ConsolidatedItemCopyWithOneLessQuantity];
如果(newItem.quantity>1)
{
newItem.consolidatedState=合并类型父项;
[sender.listOfItems replaceObjectAtIndex:j with object:newItem];
}
else if(newItem.quantity==1)
{
mycelobject*child=[sender.listOfItems objectAtIndex:j+1];
child.consolidatedState=ConsolidationTypeBasic;
[sender.listOfItems replaceObjectAtIndex:j+1 with object:child];
}
如果(newItem.quantity=0;k--)
{
nsindepath*aPath=[selectedRows objectAtIndex:k];
如果(aPath.row>=j)
{
[selectedRows replaceObjectAtIndex:k withObject:[NSIndexPath indexPathForRow:(aPath.row-1)第0节]];
}
其他的
{
打破
}
}  
path=[NSIndexPath indexPathForRow:(path.row-1)分区:0]
}
}
}
}
[sender.listOfItems removeObjectAtIn
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 the only check that will be made are on child and basic cells
    MyCellObject *item = [sender.listOfItems objectAtIndex:path.row];
    if (item.consolidatedState == ConsolidationTypeChild) 
    {
        for (int j = path.row; j >= 0; j--) 
        {
            MyCellObject *consolidatedItem = [sender.listOfItems objectAtIndex:j];
            if (consolidatedItem.consolidatedState == ConsolidationTypeParent) 
            {
                //copy the consolidated item but with 1 less quantity
                MyCellObject *newItem = [consolidatedItem copyWithOneLessQuantity];

                if (newItem.quantity > 1)
                {
                    newItem.consolidatedState = ConsolidationTypeParent;
                    [sender.listOfItems replaceObjectAtIndex:j withObject:newItem];
                }
                else if (newItem.quantity == 1)
                {
                    MyCellObject *child = [sender.listOfItems objectAtIndex:j+1];
                    child.consolidatedState = ConsolidationTypeBasic;
                    [sender.listOfItems replaceObjectAtIndex:j+1 withObject:child];
                }

                if (newItem.quantity <= 1) {

                    [sender.listOfItems removeObjectAtIndex:j];

                    // Update indexPath row values for selected items that are above the removed row

                    for (int k = i; k >= 0; k--)
                    {
                        NSIndexPath *aPath = [selectedRows objectAtIndex:k];
                        if (aPath.row >= j) 
                        {
                            [selectedRows replaceObjectAtIndex:k withObject:[NSIndexPath indexPathForRow:(aPath.row -1) inSection:0]];
                        }
                        else 
                        {
                            break;
                        }
                    }  

                    path = [NSIndexPath indexPathForRow:(path.row -1) inSection:0]
                }
            }
        }
    }

    [sender.listOfItems removeObjectAtIndex:path.row];