Pergunta

Na minha visualização de esboço, estou adicionando uma célula personalizada, para desenhar uma célula personalizada, estou me referindo ao código de exemplo, presente na documentação do Cocoa

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

Quero alterar a imagem de divulgação da célula com minha imagem customizada, tentei seguir algumas coisas

- (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];
            }
        }
}

Mas isso também não está funcionando, existe outra maneira de alterar a imagem de divulgação, também como posso descobrir em WillDisplayCell se o item é expandido ou colapso, para que eu possa definir a imagem de acordo,

Este é apenas o lugar para alterar a imagem de divulgação?

Foi útil?

Solução

Você já tem a ideia básica, mas o que precisa fazer é desenhar a imagem sozinho.Aqui está o código que eu uso:

- (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];
}

Você precisará de 3 imagens diferentes como você pode ver, uma para o ON estado, um para o OFF estadual e também um para o MIXED estado que deveria estar a meio caminho entre os dois.O estado misto garante que você ainda obtenha a animação de abertura e fechamento.

Outras dicas

Depois de pesquisar esse problema e tentar algumas das respostas aqui, descobri que as outras abordagens mencionadas funcionarão, mas exigirão que você execute muito mais intervenção manual para evitar artefatos de tela e outros comportamentos estranhos.

A solução mais simples que encontrei é a seguinte, que deve funcionar na maioria dos casos.

Esta solução tem o benefício adicional de o sistema tratar automaticamente muitos outros casos, como movimentação de colunas, etc., sem o seu envolvimento.

- (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"]];
}

No seu caso, você encerraria isso com sua lógica de detecção de classe e definiria as imagens das células adequadamente para seus casos.

Uma boa maneira de alterar a imagem de divulgação é usar uma visualização de esboço baseada em visualização:

No seu ViewController com NSOutlineViewDelegate:

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

    return cell;
}

Você precisa subclassificar seu NSOutlineView e substituir o método:

- (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;
}

Para quem procura a solução Swift2.Subclasse NSRow do seu Outlineview e substitua o método didAddSubview conforme abaixo.

override func didAddSubview(subview: NSView) {
    super.didAddSubview(subview)
    if let sv = subview as? NSButton {
        sv.image = NSImage(named:"IconNameForCollapsedState")
        sv.alternateImage = NSImage(named:"IconNameForExpandedState")
    }
}

Isso é o que tentei e trabalhei até agora,

/* porque estamos mostrando nosso próprio botão de divulgação e expansão */

- (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;
}

Eu subclassifiquei a classe NSOutlineView e substituí esses métodos,

[self isGroupItem] é para verificar se é grupo ou não.mas tenho um problema, agora parece que preciso fazer o manuseio do mouse :(, ao clicar duas vezes a linha do grupo não está alternando

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top