NSOutlineView example


NSOutlineView example



Please, could you give a simple complete example of Cocoa application with NSOutlineView with hierarchical data representation not so ambiguous like NSOutlineView and NSTreeController example
.



Thanks!





This is a case where Google is your friend. There are many examples out there.
– Chris Gregg
Jul 12 '11 at 13:32





Then drop a link Chris. I also had problems finding one which was well done
– Lothar
Aug 14 '15 at 18:18




2 Answers
2



This example uses a simple two layer hierarchy of two parents Foo and Bar who each have two kids, Foox, Foox and Barx, Barz respectively, the outline view is the default one with just two columns and the identifier of the second column is set to "children".


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

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





But the question never mentioned Cocoa Bindings
– Lothar
Aug 14 '15 at 18:20



NSOutlineView using NSURL and Swift simple example populating directory structure



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



I'm using MainWindowController with xib deleted provided window from app delegate and the IBOutlet for window


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



Example here OutlineView



It's a modified version of this example NSOutlineViewInSwift





func outlineView(outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject is a method in NSOutlineViewDataSource, not NSOutlineViewDelegate
– YangXiaoyu
Sep 24 '16 at 16:19


func outlineView(outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject


NSOutlineViewDataSource


NSOutlineViewDelegate






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

api-platform.com Unable to generate an IRI for the item of type

How to set up datasource with Spring for HikariCP?

Display dokan vendor name on Woocommerce single product pages