#cocoa #operating-system #nstableview #nsbuttoncell
#cocoa #операционная система #nstableview #nsbuttoncell
Вопрос:
У меня есть окно с 3 табличными представлениями (10.7.2, Xcode 4.2). Все они созданы в IB, и NSButtonCells соединены с выходами.
Я создал класс контроллера и заполнил все три представления некоторыми образцами данных:
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView {
return 10;
}
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
NSButtonCell *buttonCell;
if(aTableView == dimensionTable) {
[dimensionButtonCell setTitle:@"Dimension"];
buttonCell = dimensionButtonCell;
}
else if(aTableView == shopTable) {
[shopButtonCell setTitle:@"Shop"];
buttonCell = shopButtonCell;
}
else if(aTableView == countryTable) {
[countryButtonCell setTitle:@"Country"];
buttonCell = countryButtonCell;
}
return buttonCell;
}
У меня есть 2 вопроса:
-
Я не могу изменить состояние флажка через графический интерфейс. Однако я могу изменить это программно. Он немного мигает, когда вы удерживаете нажатой кнопку мыши, но не разрешает изменение…
-
Я попытался заполнить данные как с помощью views, без выходов в ячейки. Это не сработало. Ячейки NSButtonCell в представлениях ячеек каким-то образом отличаются от табличных представлений на основе view или «обычных» табличных представлений на основе cel?
Ответ №1:
После долгой борьбы мне удается найти решение проблемы. Одной из частей проблемы была простая ошибка на стороне модели данных, но это не было критичным, что-то гораздо более сложное нужно было сделать с делегатом 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, объект здесь имеет тип __NSCFBoolean , что означает, что что-то работает не так, как ожидалось. Чтобы иметь возможность заменять значение объекта на массивы, я привел его к NSCell только для получения целых значений. На самом деле это работает и без приведения, так что для меня это еще одна загадка, но так мне это нравится больше.
Очевидно, что Apple переходит к ячейкам на основе просмотра, таким как в UITableView. Тем не менее, я надеюсь, что это кому-нибудь поможет.