为了重新排列 UITableView 行,我必须实施哪些方法?

Posted

技术标签:

【中文标题】为了重新排列 UITableView 行,我必须实施哪些方法?【英文标题】:What methods do I have to implement in order to re-arrange the UITableView rows? 【发布时间】:2009-01-28 02:37:45 【问题描述】:

对于使用称为行的字符串 NSMutableArray 的简单示例,我必须在表控制器中实现什么来移动 tableView 行并将更改反映在我的数组中?

【问题讨论】:

【参考方案1】:

我们在这里进行繁重的工作。

 - (void)tableView:(UITableView *)tableView 
moveRowAtIndexPath:(NSIndexPath *)fromIndexPath 
       toIndexPath:(NSIndexPath *)toIndexPath 

    NSLog(@"move from:%d to:%d", fromIndexPath.row, toIndexPath.row);
    // fetch the object at the row being moved
    NSString *r = [rows objectAtIndex:fromIndexPath.row]; 

    // remove the original from the data structure
    [rows removeObjectAtIndex:fromIndexPath.row];

    // insert the object at the target row
    [rows insertObject:r atIndex:toIndexPath.row];
    NSLog(@"result of move :\n%@", [self rows]);

因为这是一个基本示例,所以让所有行都可以移动。

- (BOOL)tableView:(UITableView *)tableView 
canMoveRowAtIndexPath:(NSIndexPath *)indexPath 
    return YES;

【讨论】:

当 removeObjectAtIndex 被调用时,会减少该对象的引用计数(并可能导致它被释放)吗?我认为 exchangeObjectAtIndex:withObjectAtIndex: (如@dreamlax 所建议)更安全。 顺便说一句,如果您要回答自己的问题,我认为将其设为 wiki 是一种很好的形式。 @KristopherJohnson exchangeObjectAtIndex:withObjectAtIndex: 不适合这种情况。它与tableView:moveRowAtIndexPath:toIndexPath: 要求的语义不同。【参考方案2】:

以上都行不通。 在原始发布的代码中,tableview 将崩溃,因为它删除了仍在使用的数据,即使在更正之后,由于 table 执行“重新排列”的方式,数组也不会包含正确的数据。

exchangeObjectAtIndex:withObjectAtIndex: 不适用于根据 tableview 如何实现自己的重新排列来重新排列数组

为什么? 因为当用户选择一个表格单元格来重新排列它时,该单元格不会与他们移动到的单元格交换。他们选择的单元格被插入到新的行索引处,然后原始单元格被删除。至少在用户看来是这样的。

解决方案: 由于 tableview 实现重新排列的方式,我们需要执行检查以确保添加和删除正确的行。 我放在一起的这段代码很简单,非常适合我。

以贴出的原始代码数据为例:


 - (void)tableView:(UITableView *)tableView 
moveRowAtIndexPath:(NSIndexPath *)fromIndexPath 
       toIndexPath:(NSIndexPath *)toIndexPath 

    NSLog(@"move from:%d to:%d", fromIndexPath.row, toIndexPath.row);
    // fetch the object at the row being moved
    NSString *r = [rows objectAtIndex:fromIndexPath.row]; 

        // checks to make sure we add and remove the right rows
    if (fromIndexPath.row &gt toIndexPath.row) 

        // insert the object at the target row
        [rows insertObject:r atIndex:toIndexPath.row];

        // remove the original from the data structure
        [rows removeObjectAtIndex:(fromIndexPath.row + 1)];
    
    else if (fromIndexPath.row &lt toIndexPath.row) 

        // insert the object at the target row
        [rows insertObject:r atIndex:(toIndexPath.row + 1)];

        // remove the original from the data structure
        [rows removeObjectAtIndex:(fromIndexPath.row)];

    



如果您花点时间看看在重新排列期间 tableview 发生了什么,您就会明白为什么我们在原来的位置添加 1。

我对 xcode 还很陌生,所以我知道可能有更简单的方法可以做到这一点,或者代码可能可以简化....只是想尽我所能提供帮助,因为这花了我几个小时弄清楚这一点。希望这可以节省一些时间!

【讨论】:

这是TableView和NSMutableArray结合的正确答案【参考方案3】:

根据 Apple 的文档和我自己的经验,这是一些运行良好的简单代码:

NSObject *tempObj = [[self.rows objectAtIndex:fromIndexPath.row] retain];
[self.rows removeObjectAtIndex:fromIndexPath.row];
[self.rows insertObject:tempObj atIndex:toIndexPath.row];
[tempObj release];

【讨论】:

【参考方案4】:

NSMutableArray 有一个名为exchangeObjectAtIndex:withObjectAtIndex: 的方法。

【讨论】:

我试过这个,但行为不同。该表不交换行,它删除一行,然后将其插入到不同的位置。如果我使用这种方法,表和后备存储会随着每次移动而变得更加不同步。【参考方案5】:

在打破我的头脑反对一个简单的实现之后发现了这个讨论......迈克尔伯丁解决方案对我来说是最好的,苹果的方式,只记得在使用 ARC 时删除保留和释放。所以,一个更简洁的解决方案

NSObject *tempObj = [self.rows objectAtIndex:fromIndexPath.row];
[self.rows removeObjectAtIndex:fromIndexPath.row];
[self.rows insertObject:tempObj atIndex:toIndexPath.row];

【讨论】:

以上是关于为了重新排列 UITableView 行,我必须实施哪些方法?的主要内容,如果未能解决你的问题,请参考以下文章

UITableView单元格刷新问题重新排列

在运行时重新排列表格视图中的单元格

重新加载表格后 UITableView 编辑设置为 NO

用户点击编辑按钮时重做 UITableView 布局?

UIScrollView 或 UITableView 中图像的平铺排列

除了部分的特定行之外,是不是可以重新加载 UITableView?