Leo Leo - 2 months ago 87
Swift Question

Swift 3 UITableViewDataSource selectors

After updating to Swift 3 I get error in following code:

extension MyViewController: UITableViewDataSource {
//...

func tableView(_ tableView: UITableView,
heightForRowAt indexPath: IndexPath) -> CGFloat {
return someValue
}
}



Objective-C method 'tableView:heightForRowAt:' provided by method
'tableView(_:heightForRowAt:)' does not match the requirement's
selector ('tableView:heightForRowAtIndexPath:')


It can be fixed with

@objc(tableView:heightForRowAtIndexPath:)
func tableView(_ tableView: UITableView,
heightForRowAt indexPath: IndexPath) -> CGFloat {
return someValue
}


Could anyone explain motivation of signature changing in new version of Swift? There is no info in migration guide about it.

Answer

With the release of Swift 3.0 the signatures of many methods in the library have been changed for the sake of readability (see API Design Guidelines).

Compare for example the current signature of the method you quoted to its representation in the code completion drop-down menu of Xcode:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {...}

tableView(tableView: UITableView, heightForRowAt: IndexPath)

In contrast the previous implementation used to show redundant information:

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {...}

tableView(tableView: UITableView, heightForRowAtIndexPath: NSIndexPath)

Furthermore the implementation of a function or method now requires an underscore (_) to be set even for the first argument in order to allow omitting argument labels when calling the function/method (see: http://stackoverflow.com/a/38192263/6793476).

Obviously some selectors in the library haven't been updated yet so you need to provide proper ("the old") selector names (see: http://stackoverflow.com/a/39416386/6793476 and for more information about selectors: http://stackoverflow.com/a/24007718/6793476).

I hope that helps.