Peter Wiley
Peter Wiley

Reputation: 840

What is the right syntax for tableView functions in Swift 3? xCode 8 issues

I have just upgraded to xCode Version 8.0 (8A218a). I have been trying to convert some older code to Swift 3.0 and I am struggling to understand how to fix some issues with a tableView and I am confused by the documentation and some errors I am getting.

I am getting this error

*** Illegal NSTableView data source (). Must implement numberOfRowsInTableView: and tableView:objectValueForTableColumn:row:

When running this code:

class listMusicEvents: ViewController, performanceDataModelDelegate, NSTableViewDelegate, NSTableViewDataSource {

let eventModel = performanceDataModel.sharedInstance
var musicEvents:[performanceEvent] = []


@IBOutlet var tableView: NSTableView!


override func viewDidLoad() {
    super.viewDidLoad()
    eventModel.delegate = self
    tableView.delegate = self
    eventModel.getPerformanceEvents()
}

func performanceEventsLoaded() {

    musicEvents = eventModel.eventList
    print(musicEvents[0].eventTitle)
}

func performanceSaveError(headline: String, message: String, error: NSError) {
    print(error)
}

func numberOfRowsInTableView( in tableView: NSTableView) -> Int {
    return musicEvents.count
}

func tableView(_tableView:NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> AnyObject{

    if tableColumn?.title == "Date" {
        let date = musicEvents[row].eventDate
        return date as AnyObject

    } else {

        let title = musicEvents[row].eventTitle
        return title as AnyObject
    }

}

}

I thought I had implemented the new methods, but it looks like I am not understanding something basic.

I am getting a warning on the objectValueFor function:

Instance method 'tableView(tableView:objectValueForRow:row:)' nearly matches optional requirement 'tableView(:setObjectValue:for:row:) of protocol 'NSTableViewDataSource'

I've looked at the delegate docs and they say setObjectValue should not be used for a view-based tableView, which is what I have (I think).

The code I was using originally for the table column was:

tableView(tableView: NSTableView, objectValueForTableColumn tableColumn: NSTableColumn?, row: Int) -> AnyObject? { . . .

This line worked fine before brining the project into xCode 8

Can someone please explain how view-based tableViews are supposed to work with Swift 3 and what I am getting wrong? Any help very much appreciated.

Upvotes: 2

Views: 2806

Answers (3)

Ted Lowery
Ted Lowery

Reputation: 1545

Update for Swift 3

I had to use the following prototypes...auto-complete is your friend:

func numberOfRows(in tableView: NSTableView) -> Int

and

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView?

Upvotes: 1

Takashi Miyauchi
Takashi Miyauchi

Reputation: 11

I solved this problem as follows. Add NSTableViewDataSource protocol to the ViewController class.

class ViewController: NSViewController,NSTableViewDataSource{

    // snip //

    func numberOfRows(in tableView: NSTableView) -> Int {        

      // snip //

      return count
    }

    func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any?{

      // snip //

      return element
    }
}

Upvotes: 1

Peter Wiley
Peter Wiley

Reputation: 840

Restarting my computer eliminated the Illegal NSTableView data source. I guess xCode 8 worked itself into a state where it could not let go of the error.

The objectValueFor function provided by auto complete was the correct one.

Upvotes: 1

Related Questions