Remove NSElements from display from a NSOutlineView or NSTreeController

218 Views Asked by At

How can I, in a NSOutlineView, binded to a NSTreeController, driven by an NSXMLDocument, only display some NSElements (of the same type) and not others?

Thanks

1

There are 1 best solutions below

0
João Colaço On

To hide some elements the NSXMLElement has to be subclassed. The aim it's to test if one of the children of an element it's one of the ones to be hidden and remove it from the children array:

class ICoderElement:NSXMLElement{

    ///List of elements names to remove
    let nodeElementsNamesToRemove = ["title", "code"]

    override var children: [AnyObject]? {

        //get the array with all the children
        var superChildren = super.children

        //Cast the array of children to its true self
        if var trueSuperChildren = superChildren as? [NSXMLNode] {

            //Test if the array isn't empty to don't iterate over it
            if trueSuperChildren.count > 0 {

                //Iterate each of them
                for var index = 0; index < trueSuperChildren.count; index++ {
                    let node = trueSuperChildren[index]

                    //If any it's of NSXMLElement class unwarps it's name and...
                    if let nodeElement = node as? NSXMLElement, let nodeName = nodeElement.name {

                        //..tests if it's name it's o the list of elements to remove
                        //change to nodeElementsNamesToRemove.contains(nodeName) in swift2
                        if contains(nodeElementsNamesToRemove, nodeName) {

                            //Remove the child NSXMLElement from the array
                            trueSuperChildren.removeAtIndex(index)

                            //reduce the index as the array 1 less element
                            index = index - 1
                        }
                    }
                }
            }
            //returns the array without the selected elements
            return trueSuperChildren
        }
        return superChildren
    }
}

To use this class the NSXMLDocument has also to be subclassed so it can replaced with NSXMLElement:

class ICoderXMLDocument:NSXMLDocument {
    override class func replacementClassForClass(cls: AnyClass) -> AnyClass! {

        //Replace NSXMLElement by ICoderElement
        if cls === NSXMLElement.self {

            return ICoderElement.self
        }
        return cls
    }
}

From now on childCount should be used carefully. It will still return the number of child nodes from the XML file.

Because those elements are only hidden the still can be of with functions like elementsForName.