How do i make a simple view-based NSOutlineView?

后端 未结 4 1087
既然无缘
既然无缘 2021-02-05 21:40

For learning purposes i would like to convert a cell-based NSOutlineView to a view-based one,

basically i would like the following:

  • instead of a normal ce
相关标签:
4条回答
  • 2021-02-05 22:25

    I have created a little sample project which does just that.

    • Display a list of items
    • Edit the items in a master-detail fashion
    • Remove and add items
    • Usage of bindings

    Check out besi/mac-quickies on github. Most of the stuff is either done in IB or can be found in the AppDelegate

    screenshot

    0 讨论(0)
  • 2021-02-05 22:25

    Check TableViewPlayground, also View Based NSTableView Basic to Advanced from WWDC 2011.

    0 讨论(0)
  • 2021-02-05 22:30

    To return view to OutlineView column Instead of using datasource method that return objectValue:

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

    USE THE DATASOURCE METHOD THAT RETURN VIEW!!!!!!!!:

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

    everything else is the same(minimal req is the first three datasource methods, you don't need the delegate methods) but, you can't use willdisplaycell its called only for cell based , do everything to the view in the viefortablecolumn method like this:

    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;
    

    and don't forget to set identifiers , and to set the OutlineView to be View Based(in IB ...).

    0 讨论(0)
  • 2021-02-05 22:31

    OK, so you want an NSOutlineView with ImageAndTextCell cells, right?

    Let's do one of the most typical examples of this kind : a simple file explorer.

    What we'll need :

    • an NSOutlineView (put an outline to your AppDelegate, as fileOutlineView)
    • create 3 columns in the Outline with the following Identifiers (set them up in Interface Builder) : NameColumn, SizeColumn, ModifiedColumn

    Now, as for the rest, I'll do it all programmatically, so that you get a good idea of what's going on...

    How to set it up (e.g. in - (void)awakeFromNib):

    // set the Data Source and Delegate
    [fileOutlineView setDataSource:(id<NSOutlineViewDataSource>)self];
    [fileOutlineView setDelegate:(id<NSOutlineViewDelegate>)self];
    
    // set the first column's cells as `ImageAndTextCell`s
    ImageAndTextCell* iatc = [[ImageAndTextCell alloc] init];
    [iatc setEditable:NO];
    [[[fileOutlineView tableColumns] objectAtIndex:0] setDataCell:iatc];
    

    Connecting the dots :

    /*******************************************************
     *
     * 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];
            }
    
        }
    
    }
    

    Hint : ImageAndTextCell class can be found here. You'll also notice a few other methods I'm using, which are obviously NOT supported by Cocoa (e.g. isFileHidden, isFolder or folderContentsWithPathAndBackIgnoringHidden) but it's not that difficult to implement them yourself...)

    0 讨论(0)
提交回复
热议问题