NSButtonCell типа проверки в NSTableView не позволяет изменять значение

#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 вопроса:

  1. Я не могу изменить состояние флажка через графический интерфейс. Однако я могу изменить это программно. Он немного мигает, когда вы удерживаете нажатой кнопку мыши, но не разрешает изменение…

  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. Тем не менее, я надеюсь, что это кому-нибудь поможет.