I can successfully bind an NSTreeController to an NSOutlineView with Interface Builder. And when I try to do the same thing programmatically, I can also get it to work except for one little problem.
Resizing the window, to which the outline view is pinned, collapses all the open items. If I resize the outline view some other way, like putting it in an NSSplitView, moving the slider up and down does not cause any problems. It only happens when I resize the window.
The outline view is just the default one in Interface Builder. I dropped it on a window, pinned all four sides, connected the outlet to my ViewController and that's it.
Anyone have an insight? Thanks.
Here's how I create things programmatically:
override func viewWillLayout() {
super.viewWillLayout()
var treeController: NSTreeController!
@IBOutlet weak var outlineView: NSOutlineView!
var content = [TreeNode]()
newTreeController = NSTreeController.init(content: nil)
newTreeController.objectClass = TreeNode.self
newTreeController.childrenKeyPath = "children"
newTreeController.countKeyPath = "count"
newTreeController.leafKeyPath = "leaf"
newTreeController.preservesSelection = true
newTreeController.isEditable = true
newTreeController.bind("contentArray", to: self, withKeyPath: "content", options: nil)
outlineView.delegate = self
outlineView.bind("content", to: newTreeController, withKeyPath: "arrangedObjects", options: nil)
outlineView.bind("selectionIndexPaths", to: newTreeController, withKeyPath: "selectionIndexPaths", options: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
willChangeValue(forKey: "content")
// POPULATE CONTENT ARRAY
didChangeValue(forKey: "content")
}
// NSOutlineViewExtension
func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
var cellView: NSTableCellView?
if let identifier = tableColumn?.identifier {
if let view = outlineView.make(withIdentifier: identifier, owner: outlineView.delegate) as? NSTableCellView {
// view.imageView?.bind(NSValueBinding, to: view, withKeyPath: "objectValue.WHATEVER_PROPERTY", options: nil)
// view.textField?.bind(NSValueBinding, to: view, withKeyPath: "objectValue.WHATEVER_PROPERTY", options: nil)
cellView = view
}
}
return cellView
}
viewWillLayout() is the wrong place to setup the tree controller and outline view. It gets called repeatedly and is not meant for this sort of thing.
Moved everything to viewDidLoad() and problem solved.