Udało mi się to zrobić przez przy użyciu dwóch oddzielnych widoków NSTableView, które mają zsynchronizowane przewijanie NSScrollView. Aby dowiedzieć się, jak synchronizować wiele widoków przewijania (z dokładnym kodem podklasy), przeczytaj Scroll View Programming Guide for Mac - Synchronizing Scroll Views
Mam groupTableView, który ma jedną kolumnę i pokazuje widoki, które reprezentują grupę. Mam również itemTableView, który ma kolumny reprezentujące elementy grupy. Używam tych samych metod delegatów/źródeł danych z instrukcjami if-else, aby sprawdzić, który NSTableView jest używany i odpowiednio zareagować na poprawne # wierszy, widok komórki itp. Dodatkowo implementuję następującą metodę delegowania w celu dostosowania tabeli grupy wiersz wysokość view, aby być równa suma wysokości poz wierszu wierszy w grupie:
- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
{
if (tableView == self.groupTableView) {
NSUInteger firstRowIndexForGroup = ...;
NSUInteger lastRowIndexForGroup = ...;
CGFloat groupHeight = 0.0;
for (NSUInteger currentRowIndex = firstRowIndexForGroup; currentRowIndex <= lastRowIndexForGroup; currentRowIndex++) {
groupHeight += [self.itemTableView rectOfRow:lastRowIndexForGroup].size.height;
}
return groupHeight - [self.itemTableView intercellSpacing].height;
} else {
return self.itemTableView.rowHeight;
}
}
musisz również zadzwonić -noteHeightOfRowsWithIndexesChanged:
każdym razem widok tabeli potrzebuje widok grupy, ponieważ wysokość zmienia się w zależności od liczby wiersze w grupie.
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
if (tableView == self.groupTableView) {
GroupRowView *view = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
// configure view
[tableView noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndex:row]];
return view;
} else {
ItemRowView *view = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
// configure view
return view;
}
}
Wyłączyłem wybór wiersza oraz poziome i pionowe paski przewijania w widoku tabeli grupowej. Utworzyłem także poziomą siatkę dla obu widoków tabel. Na koniec ustawiam widok tabeli grupowej bezpośrednio obok widoku tabeli elementów bez żadnych przerw, więc wygląda na to, że jest to po prostu kolejna kolumna w widoku pojedynczej tabeli. Wynikiem jest bezbłędna implementacja, która ma zerowe opóźnienie między widokami tabel. Dla użytkownika wygląda tak, jakby był to pojedynczy widok tabeli.
Och, wow ... to zdecydowanie rozwiązanie, które nie wpadnie mi do głowy! Po pracy z synchronizowanym przewijaniem, zanim zobaczę, jak to działa. Prawdopodobnie jedną rzeczą do dodania jest to, że komórka grupowa zostanie kliknięta/wybrana, wówczas musiałaby "przesłać" wybór do pierwszego wiersza widoku tabeli przedmiotów. – klotz
Możesz także podzielić widok tabeli grupowej tak, aby opcjonalnie zawierał dwa wiersze na grupę, w ten sposób możesz ustawić najwyższy wiersz jako pływający nad pozostałymi, więc jeśli masz dużą grupę, informacje o grupie są przenoszone do momentu, aż ostatni element grupy zostanie przewinięty ekran. – Andrew
Co wymyśliłeś, aby wiersze tabeli elementów były zsynchronizowane z tabelą grupową? W jaki sposób zachować tabelę przedmiotów przed sortowaniem wierszy, aby nie odpowiadały grupie, w której są obok? – erynofwales