2011-07-12 12 views
9

Por favor, podría dar un ejemplo completo simple de la aplicación Cocoa con NSOutlineView con representación de datos jerárquica no tan ambigua como NSOutlineView and NSTreeController example .NSOutlineView ejemplo

Gracias!

+0

Este es un caso donde [Google es tu amigo] (http://www.google.com/search?client=safari&rls=en&q=nsoutlineview+tutorial&ie=UTF-8&oe=UTF-8). Hay muchos ejemplos por ahí. –

+2

A continuación, suelte un enlace Chris. También tuve problemas para encontrar uno que estuviese bien hecho – Lothar

Respuesta

16

Este ejemplo utiliza una jerarquía simple de dos capas de dos padres Foo y Bar, cada uno con dos hijos, Foox, Foox y Barx, Barz respectivamente, la vista de esquema es la predeterminada con solo dos columnas y el identificador del segundo la columna está configurada en "niños".

NSDictionary *firstParent = [NSDictionary dictionaryWithObjectsAndKeys:@"Foo",@"parent",[NSArray arrayWithObjects:@"Foox",@"Fooz", nil],@"children", nil]; 
NSDictionary *secondParent = [NSDictionary dictionaryWithObjectsAndKeys:@"Bar",@"parent",[NSArray arrayWithObjects:@"Barx",@"Barz", nil],@"children", nil]; 
NSArray *list = [NSArray arrayWithObjects:firstParent,secondParent, nil]; 


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

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item 
{  

    if (item == nil) { //item is nil when the outline view wants to inquire for root level items 
     return [list count];     
    } 

    if ([item isKindOfClass:[NSDictionary class]]) { 
     return [[item objectForKey:@"children"] count]; 
    } 

    return 0; 
} 

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item 
{ 

    if (item == nil) { //item is nil when the outline view wants to inquire for root level items 
     return [list objectAtIndex:index];     
    } 

    if ([item isKindOfClass:[NSDictionary class]]) { 
     return [[item objectForKey:@"children"] objectAtIndex:index]; 
    }  

    return nil; 
} 

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

    if ([[theColumn identifier] isEqualToString:@"children"]) { 
     if ([item isKindOfClass:[NSDictionary class]]) { 
      return [NSString stringWithFormat:@"%i kids",[[item objectForKey:@"children"] count]]; 
     } 
     return item; 
    }else{ 
     if ([item isKindOfClass:[NSDictionary class]]) { 
      return [item objectForKey:@"parent"];       
     }   
    } 

    return nil; 
} 

screenshot

+3

Pero la pregunta nunca mencionó Cocoa Bindings – Lothar

1

NSOutlineView usando NSURL y estructura simple ejemplo directorio poblar Swift

AppDelegate.swift

import Cocoa 

@NSApplicationMain 
class AppDelegate: NSObject, NSApplicationDelegate { 


    var mainWindowController: MainWindowController? 

    func applicationDidFinishLaunching(aNotification: NSNotification) { 
     // Insert code here to initialize your application 
     let mainWindowController = MainWindowController() 
     mainWindowController.showWindow(self) 
     self.mainWindowController = mainWindowController 

    } 

    func applicationWillTerminate(aNotification: NSNotification) { 
     // Insert code here to tear down your application 
    } 

    func applicationShouldTerminateAfterLastWindowClosed(sender: NSApplication) -> Bool { 
     return true 
    } 
} 

FileItem.swift

class FileItem { 
    var url: NSURL! 
    var parent: FileItem? 
    var isLeaf:Bool = false 
    static let fileManager = NSFileManager.defaultManager() 
    static let requiredAttributes = [NSURLIsDirectoryKey] 
    static let options: NSDirectoryEnumerationOptions = [.SkipsHiddenFiles, .SkipsPackageDescendants, .SkipsSubdirectoryDescendants] 


    lazy var children: [FileItem]? = { 
     if let enumerator = fileManager.enumeratorAtURL(self.url, includingPropertiesForKeys:FileItem.requiredAttributes, options: FileItem.options, errorHandler: nil) { 

      var files = [FileItem]() 

      while let localURL = enumerator.nextObject() as? NSURL { 
       do { 
        let properties = try localURL.resourceValuesForKeys(FileItem.requiredAttributes) 
        // check this 
        files.append(FileItem(url: localURL, parent: self, isLeaf: (properties[NSURLIsDirectoryKey] as! NSNumber).boolValue)) 
       } catch { 
        print("Error reading file attributes") 
       } 
      } 
      return files 
     } 
     return nil 
    }() 

    init(url: NSURL, parent: FileItem?, isLeaf: Bool){ 
     self.url = url 
     self.parent = parent 
     self.isLeaf = isLeaf 
    } 

    var displayName: String { 
     get { 
      return self.url.lastPathComponent! 
     } 
    } 

    var count: Int { 
     return (self.children?.count)! 
    } 

    func childAtIndex(n: Int) -> FileItem? { 
     return self.children![n] 
    } 
} 

estoy usando MainWindowController con xib borrado proporcionan ventana del delegado de la aplicación y el IBOutlet para la ventana

import Cocoa 

class MainWindowController: NSWindowController { 

    @IBOutlet weak var outline: NSOutlineView! 
    private var rootItem: FileItem? = FileItem(url: NSURL(fileURLWithPath:"/"), parent: nil, isLeaf: true) 

    override func windowDidLoad() { 
     super.windowDidLoad() 

     // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. 
    } 

    override var windowNibName: String? { 
     return "MainWindowController" 
    } 
} 

//MARK: - NSOutlineViewDelegate 
extension MainWindowController: NSOutlineViewDelegate { 

    func outlineView(outlineView: NSOutlineView, viewForTableColumn tableColumn: NSTableColumn?, item: AnyObject) -> NSView? { 
     let view = outline.makeViewWithIdentifier("TextCell", owner: self) as? NSTableCellView 
     if let it = item as? FileItem { 
      if let textField = view?.textField { 
       textField.stringValue = it.displayName 
      } 
     } else { 
      if let textField = view?.textField { 
       textField.stringValue = self.rootItem!.displayName 
      } 
     } 
     return view 
    } 
} 

//MARK: - NSOutlineViewDataSource 
extension MainWindowController: NSOutlineViewDataSource { 

    func outlineView(outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject { 
     if let it = item as? FileItem { 
      return it.childAtIndex(index)! 
     } 
     return rootItem! 
    } 
    func outlineView(outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int { 
     if let it = item as? FileItem { 
      return it.count 
     } 
     return 1 
    } 
    func outlineView(outlineView: NSOutlineView, isItemExpandable item: AnyObject) -> Bool { 
     if let it = item as? FileItem { 
      if it.count > 0 { 
       return true 
      } 
     } 
     return false 
    } 
} 

Ejemplo aquí OutlineView

Es una versión modificada de este ejemplo NSOutlineViewInSwift

+0

'func outlineView (outlineView: NSOutlineView, índice hijo: Int, ofItem elemento: AnyObject?) -> AnyObject' es un método en' NSOutlineViewDataSource', no 'NSOutlineViewDelegate' – YangXiaoyu

Cuestiones relacionadas