2011-06-06 74 views

回答

4

這取決於你如何填充你的NSTableView。

如果你有一個綁定到一個NSArrayController,又包含您的表視圖中顯示的項目表視圖,然後NSArrayController中有一個選項,以保留選擇。您可以從Interface Builder中選擇它(或不是)作爲NSArrayController的屬性。或者你可以在代碼中使用setPreservesSelection方法。

不過,如果你完全替代項目的數組NSArrayController的每一個你得到FSEvents時間管理,那麼也許選擇的保存不能工作。不幸的是,關於NSArrayController的這個屬性的Apple文檔對於何時可以並且不能保留選擇有些含糊。

如果你不使用一個NSArrayController,但也許用一個數據源來填充表視圖,那麼我認爲你必須自己管理的選擇。

+0

感謝您的解釋。我真的想用一個NSArrayController – 2011-06-09 05:59:19

+2

我發現setPreservesSelection是非常不可靠的。有時它起作用,有時它不起作用。 – 2012-09-11 15:34:02

9

那麼,你可以在調用reloadData之前保存選擇並在之後恢復。

NSInteger row = [self.tableView selectedRow]; 
[self.tableView reloadData]; 
[self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO]; 

這在某些情況下適用於我。但是,如果在選定行之前插入一些項目,則應該通過向其添加項目的計數來調整行變量。

3

@ silvansky答案的變體。

這一個沒有必要跟蹤插入/刪除項目的數量。它保持多種選擇。

想法是...
1.從當前選擇中創建一個選定對象/節點的數組。
2.刷新使用reloadData
3.在步驟1中獲得的每個對象的表,查找/記錄它的新指數
4.告訴表視圖/大綱視圖中選擇更新的索引設置

- (void)refresh { 
    // initialize some variables 
    NSIndexSet *selectedIndexes = [self.outlineView selectedRowIndexes]; 
    NSMutableArray *selectedNodes = [NSMutableArray array]; 
    NSMutableIndexSet *updatedSelectedIndex = [NSMutableIndexSet indexSet]; 

    // 1. enumerate all selected indexes and record the nodes/objects 
    [selectedIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { 
     [selectedNodes addObject:[self.outlineView itemAtRow:idx]]; 
    }]; 

    // 2. refresh the table which may add new objects/nodes 
    [self.outlineView reloadData]; 

    // 3. for each node in step 1, find the new indexes 
    for (id selectedNode in selectedNodes) { 
     [updatedSelectedIndex addIndex:[self.outlineView rowForItem:selectedNode]]; 
    } 

    // 4. tell the outline view to select the updated index set 
    [self.outlineView selectRowIndexes:updatedSelectedIndex byExtendingSelection:NO]; 
} 
+0

布拉德,你試過這個嗎? reloadData被延遲加載,所以你在調用之後不會有更新的數據。要在拖動/移動操作之後測試這個代碼,這會改變行的順序。我不認爲它會產生預期的結果。 – 2017-01-25 18:11:56

+0

@SteveSheldon我記得這個工作,但不幸的是這個項目不再運行,所以我不能再測試了。 – 2017-03-03 15:28:16

+0

@SteveSheldon,我認爲這有效;我使用了類似的技術;如果我記得,蘋果的文檔甚至提到這一點。你指的是哪些更新的數據?之後打電話? – Jerry 2017-05-02 07:13:02

3

在上reloadData()使用數據源,蘋果文檔在頭文件的情況下是

所選行不保持。

爲了解決問題,您可以使用reloadDataForRowIndexes(rowIndexes: NSIndexSet, columnIndexes: NSIndexSet)。正如在同一頭文件中提到的那樣

對於可見的單元格,將調用適當的dataSource和委託方法,並重繪單元格。

因此,數據將被重新加載,並且選擇也被保留。

4

[夫特3]

創建擴展並添加其保留選擇的方法。

extension NSTableView { 

    func reloadDataKeepingSelection() { 
     let selectedRowIndexes = self.selectedRowIndexes 
     self.reloadData() 
     self.selectRowIndexes(selectedRowIndexes, byExtendingSelection: true) 
    } 
} 

如果您使用傳統方式填充表視圖(而不是NSArrayController),請執行此操作。

+0

小記事,這將選擇第一個和上一個選定的項目,如果您只想要先前選擇的項目,將「byExtendingSelection」設置爲false – 2017-01-12 21:59:29