NSButtonCell типа Check в NSTableView не позволяет изменять значение - PullRequest
2 голосов
/ 10 ноября 2011

У меня есть окно с 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. Я пытался заполнить данные как представлениями, без выходов в ячейки.Это не сработало.Отличаются ли элементы NSButtonCell в представлениях ячеек от представлений таблиц, основанных на представлениях, или «обычных» представлений таблиц, основанных на ячейках?

1 Ответ

4 голосов
/ 15 ноября 2011

После долгой борьбы мне удается найти решение проблемы. Одной из частей проблемы была простая ошибка на стороне модели данных, но она не была критической, что-то намного более трудное было сделать с делегатом 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. Тем не менее, я надеюсь, что это кому-нибудь поможет.

...