NSOutlineView Изменение раскрытия изображения - PullRequest
3 голосов
/ 18 февраля 2011

В моем виде структуры я добавляю пользовательскую ячейку. Для рисования пользовательской ячейки я использую пример кода, представленный в документации по какао

http://www.martinkahr.com/2007/05/04/nscell-image-and-text-sample/

Я хочу изменить раскрывающее изображение ячейки своим собственным изображением, я попробовал следующие вещи

- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item 
    {
        if([item isKindOfClass:[NSValue class]])
        {
            MyData *pDt = (MyData *)[item pointerValue];
            if(pDt->isGroupElement())
            {
                [cell setImage:pGroupImage];
            }
        }
}

но это тоже не работает, есть ли другой способ изменить изображение раскрытия, также, как я могу узнать в willDisplayCell, является ли элемент развернутым или развернутым, чтобы я мог соответственно установить изображение,

Это единственное место, где можно изменить изображение раскрытия?

Ответы [ 5 ]

4 голосов
/ 07 марта 2013

После исследования этой проблемы самостоятельно и пробуя некоторые ответы здесь, я обнаружил, что другие упомянутые подходы будут работать, но потребуют, чтобы вы выполняли намного больше ручного вмешательства, чтобы избежать артефактов экрана и другого странного поведения.

Самое простое решение, которое я нашел, это следующее, которое должно работать в большинстве случаев.

Это решение имеет дополнительное преимущество, заключающееся в том, что система автоматически обрабатывает множество других случаев, таких как перемещение столбцов и т. Д., Без вашего участия.

- (void)outlineView:(NSOutlineView *)outlineView willDisplayOutlineCell:(id)cell
     forTableColumn:(NSTableColumn *)tableColumn
               item:(id)item
{
    [cell setImage:[NSImage imageNamed: @"Navigation right 16x16 vWhite_tx"]];
    [cell setAlternateImage:[NSImage imageNamed: @"Navigation down 16x16 vWhite_tx"]];
}

В вашем случае вы бы обернулиэто с вашей логикой обнаружения класса, и установить изображения ячеек в соответствии с вашими делами.

1 голос
/ 05 сентября 2016

Для тех, кто ищет решение Swift2. Подкласс NSRow вашего outlineview и переопределите метод didAddSubview, как показано ниже.

override func didAddSubview(subview: NSView) {
    super.didAddSubview(subview)
    if let sv = subview as? NSButton {
        sv.image = NSImage(named:"IconNameForCollapsedState")
        sv.alternateImage = NSImage(named:"IconNameForExpandedState")
    }
}
1 голос
/ 10 февраля 2015

Хороший способ изменить изображение раскрытия состоит в том, чтобы использовать представление контура на основе вида:

В вашем ViewController с NSOutlineViewDelegate:

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
    CustomNSTableCellView *cell    = [outlineView makeViewWithIdentifier:tableColumn.identifier owner:self];
    cell.item                      = item;

    return cell;
}

Вы должны создать подкласс NSOutlineViewи overide метод:

- (id)makeViewWithIdentifier:(NSString *)identifier owner:(id)owner
{
    id view = [super makeViewWithIdentifier:identifier owner:owner];

    if ([identifier isEqualToString:NSOutlineViewDisclosureButtonKey])
    {
        // Do your customization
        // return disclosure button view

        [view setImage:[NSImage imageNamed:@"Disclosure_Categories_Plus"]];
        [view setAlternateImage:[NSImage imageNamed:@"Disclosure_Categories_Minus"]];
        [view setBordered:NO];
        [view setTitle:@""];

        return view;
    }

    return view;
}

//Frame of the disclosure view
- (NSRect)frameOfOutlineCellAtRow:(NSInteger)row
{
    NSRect frame = NSMakeRect(4, (row * 22), 19, 19);
    return frame;
}
1 голос
/ 18 февраля 2011

У вас есть основная идея, но вам нужно нарисовать изображение самостоятельно. Вот код, который я использую:

- (void)outlineView:(NSOutlineView *)outlineView willDisplayOutlineCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item {
    NSString *theImageName;
    NSInteger theCellValue = [cell integerValue];
    if (theCellValue==1) {
        theImageName = @"PMOutlineCellOn";
    } else if (theCellValue==0) {
        theImageName = @"PMOutlineCellOff";
    } else {
        theImageName = @"PMOutlineCellMixed";
    }

    NSImage *theImage = [NSImage imageNamed: theImageName];
    NSRect theFrame = [outlineView frameOfOutlineCellAtRow:[outlineView rowForItem: item]];
    theFrame.origin.y = theFrame.origin.y +17;
    // adjust theFrame here to position your image
    [theImage compositeToPoint: theFrame.origin operation:NSCompositeSourceOver];
    [cell setImagePosition: NSNoImage];
}

Вам понадобятся 3 различных изображения, как вы можете видеть, одно для состояния ON, одно для состояния OFF и одно для состояния MIXED, которое должно быть посередине между ними. В смешанном состоянии вы по-прежнему получаете анимацию открытия и закрытия.

0 голосов
/ 18 февраля 2011

Это то, что я пробовал и работаю до сих пор,

/ *, потому что мы показываем нашу собственную кнопку раскрытия и расширения * /

- (NSRect)frameOfOutlineCellAtRow:(NSInteger)row {

    return NSZeroRect;
}
- (NSRect)frameOfCellAtColumn:(NSInteger)column row:(NSInteger)row {
    NSRect superFrame = [super frameOfCellAtColumn:column row:row];

    if ((column == 0) && ([self isGroupItem:[self itemAtRow:row]])) {
        return NSMakeRect(0, superFrame.origin.y, [self bounds].size.width, superFrame.size.height);
    }
    return superFrame;
}

У меня есть класс NSOutlineView и переопределитьэтими методами

[self isGroupItem] является проверка, является ли его группа или нет.но есть одна проблема, теперь выглядит как манипулирование мышью, что мне нужно сделать :(, при двойном щелчке группа строки не переключается

...