0

I'm working on an NSOutlineView that uses NSView subclasses to generate custom cells in the outline. This I've gotten to work, BUT after the Outline sucks in the data from the model class and displays it correctly, the Outline is released(?) from memory / goes to nil and I haven't figured out a way to get it back.

Here is the MainViewController class

class MainWindowController: NSWindowController, ShareInfoDelegate,    NSOutlineViewDelegate, NSOutlineViewDataSource {

override var windowNibName: String {

    return "MainWindowController"

}

@IBOutlet var daOutline: NSOutlineView!
//  The NSoutline I'm trying to get back to    

Some stuff related to the test data (Omitted) leading us to the NSOutlineViewDataSource stuff

//MARK: - NSOutlineViewDataSource

func outlineView(outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject {
    if let item: AnyObject = item {
        switch item {
        case let work as Work:
            return work.movements[index]

        case let movement as Movement:
            return movement.tracks[index]

        default:

            let track = item as! Track
            return track.credits[index]
        }
    } else {
        if allWorks.count > 0 {

            return allWorks[index]
        }
    }
    let q = "patience"
    return q
}

func outlineView(outlineView: NSOutlineView, isItemExpandable item: AnyObject) -> Bool {
    switch item {
    case let work as Work:
        return (work.movements.count > 0) ? true : false

    case let movement as Movement:
        return (movement.tracks.count > 0) ? true : false

    case let track as Track:
        return (track.credits.count > 0) ? true: false

    default:
        return false
    }
}

func outlineView(outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int {
    if let item: AnyObject = item {
        switch item {
        case let work as Work:
            return work.movements.count

        case let movement as Movement:
            return movement.tracks.count

        case let track as Track:
            return track.credits.count

        default:
            return 0
        }
    } else {
        return allWorks.count
    }
}



func outlineView(daOutline: NSOutlineView, viewForTableColumn theColumn: NSTableColumn?, item: AnyObject) -> NSView? {

          switch item {

        case let worked as Work:

            let cell = daOutline.makeViewWithIdentifier("newTry", owner:self) as! newTry

            cell.fourthLabel.stringValue = worked.composer

            cell.fourthCell.stringValue = worked.title

            return cell


        case let moved as Movement:

            let cell2 = daOutline.makeViewWithIdentifier("SecondTry", owner:self) as! SecondTry

            cell2.roman.stringValue = moved.name!

            cell2.details.stringValue = moved.sections!

            cell2.track.stringValue = "0"

            return cell2


        default:

            print("probably not")
    }

    print("not again")
    return nil
}

func outlineView(daOutline: NSOutlineView, heightOfRowByItem item: AnyObject) -> CGFloat {

    switch item {

    case let worked as Work:
        return 40

    default:
        return 24

    }        
}

And the stuff in WindowDidLoad

    override func windowDidLoad() {
    super.windowDidLoad()

    let nib = NSNib(nibNamed: "newTry", bundle: NSBundle.mainBundle())
    daOutline.registerNib(nib!, forIdentifier: "newTry")

    let nib2 = NSNib(nibNamed: "SecondTry", bundle: NSBundle.mainBundle())
    daOutline.registerNib(nib2!, forIdentifier: "SecondTry")

    //give Sender it's Receiver
    mailItOut.delegate = receiver

    allWorks.append(work1)
    allWorks.append(work2)

    work1.movements.append(move1)
    work1.movements.append(move2)
    work1.movements.append(move3)
    work1.movements.append(move4)

    work2.movements.append(move5)
    work2.movements.append(move6)
    work2.movements.append(move7)

    daOutline.reloadData()

    daOutline?.expandItem(work1, expandChildren: false)

   daOutline?.expandItem(work2, expandChildren: false)
}

}

And Finally what the newTry NSView class looks like

class newTry: NSView {

var delegate: ShareInfoDelegate?



@IBOutlet weak var fourthCell: NSTextField!

@IBOutlet weak var fourthLabel: NSTextField!



@IBAction func cellAdd(sender: NSTextField) {

    var catchIt: String = String()



    catchIt = sender.stringValue

    if catchIt != "" {
     tryAgain = catchIt

    whichField = "title"

    //Trigger the sender to send message to it's Receiver
    mailItOut.sendMessage()

    }
}

The cellAdd Action is used to try and get user input from the text cells back into the model. To do this I (AFAIK) need to access the NSOutline (daOutline) and get which row I'm at and put the data from the sender into the appropriate part of the Model class. Which is something that I've managed to get to work in a standard (1 cell / 1 data value) outline. But in this prototype, as far as I can tell, the MainWindowController has released all of its contents and daOutline is nil (bad).

How do I get XCode to bring / reload the completed outline (or never release it) and get daOutline to a non nil state?

Community
  • 1
  • 1
ArtbyKGH
  • 163
  • 3
  • 7

1 Answers1

0

For those who come after there appeared to be two problems that led to the NSOutline outlet becoming nil. The first one was that in implementing the delegate protocol "shareInfoDelegate" I was creating a new instance of the MainWindowController, not the one with the data in it. This new instance did NOT have the IBOutlets connected (or much of anything useful about it). Once I scrapped the Delegate and moved to using NSNotification to update information about the NSView textFields my NSOutline came "back".

The second, more minor, problem was that in the NSView nib file I placed and NSBox to mimic the behavior of a group row (e.g. a gray background). As a side effect the NSBox was inhibiting the normal row select behavior of the outline. Which made it very hard to determine which row was selected. When I deleted the NSBox, row selection became much more easy to determine.

in particular this Question and the answer by Chuck were helpful in sniffing this out.

Why is my NSOutlineView datasource nil?

Thanks Indeed(!)

Community
  • 1
  • 1
ArtbyKGH
  • 163
  • 3
  • 7