2011-11-29 55 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