NSTableView + NSSegmentedControl + NSSegmentSwitchTrackingSelectAny

У меня есть табличное представление, которое имеет NSSegmentedCell для самого правого столбца.

Элементы NSSegmentedControls, из которых извлекаются ячейки, используют режим отслеживания "любой" (он же множественный выбор), и сегменты выбираются на основе битового поля с возможными значениями: 1, 2 и 4. Значение 1 означает A|b. | гр. 2 является |B|c. 4 является |b|C. 3 - это A|B|c и т. Д.

Это битовое поле возвращается из источника данных tableView:objectValueForTableColumn:row: метод, а ячейка возвращается в делегат tableView: dataCellForTableColumn: row: метод.

Установка ячеек по отдельности в tableView: dataCellForTableColumn: row: ничего не делает, потому что табличное представление вызывает tableView:objectValueForTableColumn:row: сразу после этого, чтобы получить значение для этого столбца, а затем использует его для установки "значения" Сегментированный контроль / ячейка.

Проблема в этом.

Похоже, что битовое поле неправильно интерпретируется как значение индекса сегмента: 0 для A, 1 для B и 2 для C (и -1 для отсутствия выбора).... что предполагает один выбор.

Как мне установить это так, чтобы табличное представление правильно установило несколько сегментов? (например: битовое поле 3 = A|B|c)

1 ответ

Я сделал это так, и это работает:
1) убедитесь, что в методах источника данных / делегата вашей таблицы есть ссылка на сегментированную контрольную ячейку; в моем проекте я просто соединил сегментированную управляющую ячейку со свойством outlet в своем классе контроллера представления

2) вернуть что-либо из метода получения источника данных таблицы для столбца с сегментированным управлением (в моем проекте repeatDays - это идентификатор этого столбца), например, nil

 - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex {
    NSString *colId = [tableColumn identifier];

    if ([colId isEqualToString:@"repeatDays"]) {
        return nil;
    }

    //handle other columns
}

3) реализовать метод willDisplayCell делегата tableview

- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    NSString *colId = [tableColumn identifier];

    if ([colId isEqualToString:@"repeatDays"]) {
        for (int i = 0; i < self.segmentedCell.segmentCount; ++i) {
            BOOL selected = [[self.days objectForKey:[NSNumber numberWithInt:i]] boolValue];
            [self.segmentedCell setSelected:selected forSegment:i];
        }
    }
}

вам нужно настроить сегментированную ячейку, когда табличное представление собирается ее отобразить, сделать это в соответствии с деталями вашей модели, например, в моем проекте у меня есть изменяемый словарь дней, и он содержит значения bool, соответствующие сегментам, например {0: NO, 1: ДА, 2: НЕТ, 3: ДА, 4: НЕТ, 5: НЕТ, 6: НЕТ}, где 0, 1, 2, 3, 4, 5, 6 - сегменты, а ДА / НЕТ - будь это сегмент выбран или нет

4) последний, реализующий метод установки источника данных tableview; переданный ему объект кликается по индексу сегмента; измените вашу модель соответствующим образом, то есть установите флажок для индекса сегмента клика:

- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    NSString *colId = [tableColumn identifier];

    if ([colId isEqualToString:@"repeatDays"]) {
        int i = [object intValue];
        BOOL selected = [[self.days objectForKey:[NSNumber numberWithInt:i]] boolValue];
        [self.days setObject:[NSNumber numberWithBool:!selected] forKey:[NSNumber numberWithInt:i]];
    }
}
Другие вопросы по тегам