После долгой борьбы мне удается найти решение проблемы. Одной из частей проблемы была простая ошибка на стороне модели данных, но она не была критической, что-то намного более трудное было сделать с делегатом NSTableView и источником данных.
В основном было 3 трудности, которые мешали хорошему пониманию и решению этой проблемы:
В документации Apple отсутствуют какие-либо разумные объяснения различий и типичное использование - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
в источнике данных табличного представления и - (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
его делегата. Хотя может показаться, что вам понадобится последний метод, поскольку NSButtonCells являются пользовательскими NSCells, оказывается, что в этом нет необходимости, но я все равно оставил его в конце.
внутренние преобразования в методах NSTableView
проблема не задокументирована практически нигде в сети
Вот шаги, которые вы должны сделать:
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
buttonCell = [aTableColumn dataCell];
NSString *columnKey = [aTableColumn identifier];
return buttonCell;
}
Вы можете видеть, что этот метод должен быть реализован независимо от того, используете вы его или нет.
- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
buttonCell = [tableColumn dataCell];
NSString *columnKey = [tableColumn identifier];
if(tableView == dimensionTable) {
// returnObject = @"Dimension";
// [dimensionButtonCell setTitle:@"Dimension"];
// buttonCell = dimensionButtonCell;
}
else if(tableView == shopTable) {
[buttonCell setState:[[mySelectedShops objectAtIndex:row] integerValue]];
[buttonCell setTitle:[myShops objectAtIndex:row]];
}
else if(tableView == countryTable) {
[buttonCell setState:[[mySelectedCountries objectAtIndex:row] integerValue]];
[buttonCell setTitle:[myCountries objectAtIndex:row]];
}
return buttonCell;
}
Вы можете видеть, что я использовал второй метод, однако objectValueForTableColumn
мог использоваться исключительно.
Вы также можете видеть, у меня есть NSMutableArray mySelectedShops и mySelectedCountries для хранения NSInteger (1 или 0), обернутого в NSNumber для каждой строки в табличном представлении.
Если вы установите состояние или целочисленное значение NSCell, не имеет значения. Оба будут проверять и снимать флажок NSButtonCell со значениями 1 или 0 типа NSInteger.
- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
NSString *columnKey = [aTableColumn identifier];
if(aTableView == dimensionTable) {
// [dimensionButtonCell setTitle:@"Dimension"];
// buttonCell = dimensionButtonCell;
}
else if(aTableView == shopTable) {
[mySelectedShops replaceObjectAtIndex:rowIndex withObject:[NSNumber numberWithInteger:[(NSCell*)anObject integerValue]]];
}
else if(aTableView == countryTable) {
[mySelectedCountries replaceObjectAtIndex:rowIndex withObject:[NSNumber numberWithInteger:[(NSCell*)anObject integerValue]]];
}
}
Хотя я передал значение NSInteger объекту NSCell, здесь объект anObject имеет тип __NSCFBoolean, что означает, что что-то работает не так, как ожидалось. Чтобы иметь возможность заменить значение объекта на массивы, я преобразовал его в NSCell только для получения integerValues. Это на самом деле работает и без актеров, так что для меня это еще одна загадка, но мне это нравится больше.
Ясно, что Apple переходит к просмотру ячеек на основе, как в UITableView. Тем не менее, я надеюсь, что это кому-нибудь поможет.