Apple changed NSPathControl to work with NSPathControlItem's in Yosemite.
But from where I am sitting, these new classes don't work at all. I am trying to display a custom path in my data structures, but I have similar problems with a regular file path. Is it me or is it Apple?
Here is my code:
The first snippet works as in, it will show a path. But that is about all that works.
//MARK: notifications
func selectionDidChange(notification : NSNotification)
{
if let item = notification.object as? Group
{
//get "path" components
var components : [String] = [item.title ?? "a"]
var ancestor : Group? = item.parent
while (ancestor != nil)
{
components.append(ancestor?.title ?? "b")
ancestor = ancestor?.parent
}
components.append("")
//convert to url
let path = ("MyScheme:/" + "/".join(components.reverse()))
pathControl?.URL = NSURL(string: path.stringByAddingPe
}
}
Clicking any part of the path to try to get any property out of the NSPathControlItem does not work at all. Everything returns nil.
@IBAction func select(sender : AnyObject)
{
println(sender.clickedPathItem??.title)
println(sender.clickedPathItem??.URL)
}
If I try to build a path with NSPathControlItem, I can not set any properties (title, url).
pathComponent.URL = NSURL(string: path.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!)
//let url : NSURL? = NSURL(string: "/")
//let path = NSURL(fileURLWithPath: "/")
//pathComponent.URL = path as NSURL
pathComponent.attributedTitle = NSAttributedString(string: "/atttributes")
self.pathControl?.pathItems = [pathComponent]
println(pathComponent.description)
Also NSPathControlItem is not supposed to be subclassed.
What is going on here?
edit
There is a problem with NSPathControlItem as far as I can tell. A helper function to create a NSPathControlItem.
func pathItem(title: String, imageName: String) -> NSPathControlItem
{
let item = NSPathControlItem()
item.title = title
item.image = NSImage(named: imageName)
return item
}
A test function to create NSPathControlItem's and print out their title.
var pathItems : [NSPathControlItem] = []
for title in ["a","b","c"]
{
pathItems.append(self.pathItem(title, imageName: NSImageNameFolder))
}
for item in pathItems
{
println(item.title)
}
The expected output is three lines with a, b and c. I get nil, b, nil.
If you set the pathItems on a NSPathControl directly, it will work.
self.pathControl?.pathItems = [
self.pathItem("a", imageName: NSImageNameFolder),
self.pathItem("b", imageName: NSImageNameFolder),
self.pathItem("c", imageName: NSImageNameFolder)]
However, if you set the pathItems indirectly, all goes to hell.
self.pathControl?.pathItems = pathItems //array of NSPathControl (see above)
Edit 2
I had another look at this. I configure a NSPathControlItem in the pathItem function. Here I set the title. Makes no difference if I set the attributedTitle. Inspecting the item with lldb shows the correct (attributed)title value.
But when I assign the array of NSPathControlItem's to the NSPathControl, the title has a value of "" and the attributedTitle is uninitialized.
NSPathControlItem
is seriously broken. As of 10.11.3, it contains the following method, as decompiled by Hopper:This is evidently supposed to be a standard
dealloc
override, which releases the ivar, zeroes it out, and calls super. But instead, for some unknown reason possibly related to illegal drugs, it's arelease
override. This means that the moment one of these objects is released, even in the course of some harmless manipulation, it self-destructs and becomes unusable.I created some code to use the runtime to eliminate the bad
release
override and substitute in a properdealloc
override. This is barely tested and use at your own risk: