2011-11-29 48 views
2

我一直在查看NSTableViewmoveRowAtIndex:toIndex动画表中的行的方法。尽管从我所知道的排序来看,它并没有什么帮助。我对它的工作原理的解释是,如果我想将行0移动到行4,那么它们之间的行将得到适当的处理。但是,如果我有一个支持它的数组的表视图,然后对数组进行排序,我希望表视图可以从旧状态动画到新状态。我不知道哪些东西是移动的,而移动的东西是为了适应移动的东西。使用开始和结束数组状态动画NSTableView

例子:

[A,B,C,D] --> [B,C,D,A] 

我知道,行0移到第3行,所以我会说[tableView moveRowAtIndex:0 toIndex:3]。但是,如果我对[A,B,C,D]应用某种自定义排序操作​​使其看起来像[B,C,D,A],实际上我不知道第0行移至第3行而不是第1行,2和3移动到行0,1和2.我认为我应该能够指定所有的移动(行0移动到行4,行1移动到行0等),但是当我尝试时动画看起来不正确。

有没有更好的方法来做到这一点?

编辑:我发现this site,这似乎做我想要什么,但似乎有点像很多的东西,应该是简单的(至少我认为它应该是简单的)

回答

5

为moveRowAtIndex的文档:toIndex:他说:“变化发生在桌子上时发生变化”。

从ABCDE到ECDAB的转换可以很好地说明“增量式”的意义。

如果你只考虑最初和最后的指标,它看起来像:

E: 4->0 (array is now EABCD) 
C: 3->1 (array is now ECABD) 
D: 4->2 (array is now ECDAB) 
A: 3->3 (array unchanged) 
B: 4->4 (array unchanged) 

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

然而,逐步进行更改时的“初始”的索引可以为你改变你的阵列跳来跳去

基本上,您需要逐步告诉NSTableView需要移动哪些行才能到达与您的排序数组完全相同的数组。

这里是一个非常简单的实现,需要一个任意排序的阵列和“重播”原始数组转换为有序阵列所需的动作:

// 'backing' is an NSMutableArray used by your data-source 
NSArray* sorted = [backing sortedHowYouIntend]; 

[sorted enumerateObjectsUsingBlock:^(id obj, NSUInteger insertionPoint, BOOL *stop) { 

    NSUInteger deletionPoint = [backing indexOfObject:obj]; 

    // Don't bother if there's no actual move taking place 
    if (insertionPoint == deletionPoint) return; 

    // 'replay' this particular move on our backing array 
    [backing removeObjectAtIndex:deletionPoint]; 
    [backing insertObject:obj atIndex:insertionPoint]; 

    // Now we tell the tableview to move the row 
    [tableView moveRowAtIndex:deletionPoint toIndex:insertionPoint]; 
}]; 
+0

这看起来很相似,我试图想出用。虽然我没有测试过这个版本,但我认为潜在的问题是,为了使动画平滑,我必须弄清楚moveRowAtIndex调用的最小数量会将未排序的数组转换为已排序的数组。 – JPC

+0

'增量'问题只与改变NSTableView的内部管理有关,并且与动画平滑无关。 只要您用beginUpdates和endUpdates括起您的更改,它将始终执行最少的行移动次数,可能会比您预期的更多移动次数。 例如ABCDE - > EABCD只是一个“移动”,但所有行的位置都会受到影响(假设所有行都在屏幕上可见),所以所有行都会生成动画。 –

+0

嗯。我会再看看它,但至少从我的观察中我已经看到一些生涩的动画 – JPC