Как сделать простой NSOutlineView на основе представлений?

В целях обучения я хотел бы преобразовать NSOutlineView на основе ячеек на основе представления,

в основном я бы хотел:

  • вместо нормальной ячейки, мне бы хотелось, чтобы "вид ячейки изображения и текстовой таблицы"
  • изображение может быть запасом NSApplicationIcon, и текст может быть просто "hello world":)
  • Я хотел бы сделать это без использования привязок и NSTreeController

Вот пример "простых в мире NSOutlineView" http://www.cocoasteam.com/Cocoa_Steam/Worlds_Simplest_Demo.html

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

Я пробовал смотреть на примеры с яблоками и искать в другом месте в Интернете, но я до сих пор не могу заставить его работать - так спасибо заблаговременно:)

Ответ 1

ОК, так что вы хотите NSOutlineView с ячейками ImageAndTextCell, правильно?

Сделайте один из наиболее типичных примеров такого рода: простой проводник файлов.

Что нам нужно:

  • a NSOutlineView (нарисуйте контур вашего AppDelegate, как fileOutlineView)
  • создайте 3 столбца в контуре со следующими Идентификаторами (настройте их в Interface Builder): NameColumn, SizeColumn, ModifiedColumn

Теперь, что касается остальных, я сделаю все это программно, так что вы получите хорошее представление о том, что происходит...

Как настроить его (например, в - (void)awakeFromNib):

// set the Data Source and Delegate
[fileOutlineView setDataSource:(id<NSOutlineViewDataSource>)self];
[fileOutlineView setDelegate:(id<NSOutlineViewDelegate>)self];

// set the first column cells as `ImageAndTextCell`s
ImageAndTextCell* iatc = [[ImageAndTextCell alloc] init];
[iatc setEditable:NO];
[[[fileOutlineView tableColumns] objectAtIndex:0] setDataCell:iatc];

Подключение точек:

/*******************************************************
 *
 * OUTLINE-VIEW DATASOURCE
 *
 *******************************************************/

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{        
    if ([item isFolder])
        return YES;
    else
        return NO;
}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{    
    if (item==nil)
    {
        // Root
        return [[filePath folderContentsWithPathAndBackIgnoringHidden] count];
    }
    else
    {        
        if ([item isFolder])
        {
            return [[item folderContentsWithPathAndBackIgnoringHidden] count];
        }
        else
        {
            return 0;
        }
    }
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
    if (item == nil)
    { 
        // Root
        return [[filePath folderContentsWithPathAndBackIgnoringHidden] objectAtIndex:index];
    }

    if ([item isFolder])
    {
        return [[item folderContentsWithPathAndBackIgnoringHidden] objectAtIndex:index];
    }

    // File
    return nil;
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)theColumn byItem:(id)item
{          
    if ([[theColumn identifier] isEqualToString:@"NameColumn"])
    {
        return [item lastPathComponent];
    }
    else if ([[theColumn identifier] isEqualToString:@"SizeColumn"])
    {
        if ([item isFolder]) return @"--";
        else return [NSString stringWithFormat:@"%d",[item getFileSize]];
    }
    else if ([[theColumn identifier] isEqualToString:@"ModifiedColumn"])
    {
        if ([item isFolder]) return @"";
        else return [NSString stringWithFormat:@"%@",[item getDateModified]];
    }

    // Never reaches here
    return nil;
}

/*******************************************************
 *
 * OUTLINE-VIEW DELEGATE
 *
 *******************************************************/

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item
{
    return YES;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item
{
    return NO;
}

- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item {
    [cell setDrawsBackground:NO];

    if ([item isFileHidden]) [cell setTextColor:[NSColor grayColor]];
    else [cell setTextColor:[NSColor whiteColor]];

    if ([[tableColumn identifier] isEqualToString:@"NameColumn"])
    {
        if ([item isFolder])
            [cell setImage:[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericFolderIcon)] size:15.0];
        else
            [cell setImage:[[NSWorkspace sharedWorkspace] iconForFile:item] size:15.0];

        if ([item isFileHidden])
        {
            [cell setFileHidden:YES];
        }
        else
        {
            [cell setFileHidden:NO];
        }

    }

}

Подсказка: ImageAndTextCell можно найти здесь. Вы также заметите несколько других методов, которые я использую, которые, очевидно, НЕ поддерживаются Cocoa (например, isFileHidden, isFolder или folderContentsWithPathAndBackIgnoringHidden), но это не так сложно реализовать их самостоятельно...)

Ответ 2

Я создал небольшой примерный проект, который делает именно это.

  • Отобразить список элементов
  • Отредактируйте элементы в режиме мастер-детали.
  • Удалить и добавить элементы
  • Использование привязок

Обратите внимание на besi/mac-quickies на github. Большая часть материала либо выполняется в IB, либо может быть найдена в AppDelegate

screenshot

Ответ 3

Чтобы вернуться к столбцу OutlineView Вместо использования метода источника данных, возвращающего objectValue:

  • (id) outlineView: (NSOutlineView *) outlineView objectValueForTableColumn: (NSTableColumn *) theColumn byItem: (id) item

ИСПОЛЬЗУЙТЕ МЕТОД ДАТУСУРСОВ, КОТОРЫЙ ВОЗВРАЩАЕТСЯ ВЗГЛЯД!!!!!!!!:

  • (NSView *) outlineView: (NSOutlineView *) outlineView viewForTableColumn: (NSTableColumn *) tableColumn item: (id) item

все остальное одно и то же (минимальный req - первые три метода источников данных, вам не нужны методы делегата), но, вы не можете использовать willdisplaycell, который он вызывается только для ячейки, все делает для представления в методе viefortablecolumn следующим образом:

if ([[tableColumn identifier] isEqualToString:@"YourColumnIdentifier"]){
    NSTableCellView *cell = [outlineView makeViewWithIdentifier:@"YourViewsIdentifier" owner:self];
    [cell.textField setStringValue:[(YourItem *)item name]];
    [cell.imageView setImage:[(YourItem *)item image]];
    return cell;
}

return nil;

и не забудьте установить идентификаторы и настроить OutlineView на просмотр (в IB...).

Ответ 4

Отметьте TableViewPlayground, а также View Based NSTableView Basic to Advanced от WWDC 2011.