I am getting an error when coding, saying
Type "ViewController" does not conform to protocol "UITableViewDataSource"
Can anyone tell what went wrong with this?
import UIKit
class ViewController: UIViewController, UITableViewDataSource{
let devCourses = [
("Math"),
("Science"),
("English"),
("Computer Programming"),
("Physics")]
func numberOfSectionsInTableview(tableview: UITableView)-> Int {
return 1
}
func tableview(tableView: UITableView, numberOfRowsInSection section: Int) ->Int{
return devCourses.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let (courseTitle) = devCourses[indexPath.row]
cell.textLabel?.text = courseTitle
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This is a common mistake, please make sure you use the correct words. In your case it should be:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return devCourses.count
}
not
func tableview(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return devCourses.count
}
You must use tableView instead of tableview. It is case sensitive
I think you are missing some functions for that are required by the delegate:
The declaration should be changed to include:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
and then you make sure all the required methods for a table are there:
func tableView(tableView:UITableView!, numberOfRowsInSection section:Int) -> Int
and
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
and invoke delegate on ViewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
yourtableview.dataSource = self
// Do any additional setup after loading the view.
}
Hope this helps
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var alphNames = ["ABC","DEF","GHI","JKL","MNO","PQR","STU"]
func tableView(tableView: UITableView, numberofRowInsection section: Int) -> Int {
return alphNames.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath : indexPath) as UITableViewCell
//Configure the cell...
cell.textLabel?.text = departmentNames[indexPath.row]
return cell
}
}
You made an typo in numberOfRowsInSection function. It is a required function of the UITableViewDataSource protocol. It should be
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return alphNames.count
}
You have typed numberofRowInsection instead.
You have to implement all the required functions. You can see them by command clicking on the UITableViewDataSource. To make sure you don't make any typo, just copy the required functions or start typing in the ViewController the name of the function and autocompletion should do the rest.
This question was asked multiple times.
http://stackoverflow.com/questions/25581780/type-viewcontroller-does-not-confirm-to-protocol-uitableviewdatasource
and I did tried the solutions provided over there but still I am not able to get away with this error. Code to UITableView is below
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
{
#IBOutlet var tableView: UITableView!
var data: [String] = ["one","two","three","four"]
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return self.data.count;
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath!)
{
println("You clicked cell number #\(indexPath.row)!")
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
{
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel?.text = self.data[indexPath.row]
return cell
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Please tell what mistake am I doing here.
Try this just remove both the function numberOfRowsInSection and cellForRowAtIndexPath and again add this function like :
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return self.data.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel?.text = self.data[indexPath.row]
return cell
}
This is works for me.
The following code didn't work for me on iOS 8.1. in XCode 6.1.1. This code works:
import UIKit
class ViewController : UIViewController,UITableViewDelegate,UITableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
//currently only a testing number
return 25
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var cell:UITableViewCell=UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "mycell")
cell.textLabel?.text = "row#\(indexPath.row)"
cell.detailTextLabel?.text = "subtitle#\(indexPath.row)"
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Please confirm all tableview required methods before the last }. Like
class ViewController:UIViewController,UITableViewDataSource,UITableViewDelegate {
var data: [String] = ["one","two","three","four"]
override func viewDidLoad() {
super.viewDidLoad()
self.loadTableView()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func loadTableView() {
var tableObj:UITableView=UITableView()
tableObj=UITableView(frame: UIScreen.mainScreen().bounds, style: UITableViewStyle.Plain)
tableObj.delegate=self;
tableObj.dataSource=self;
self.view.addSubview(tableObj)
}
// MARK: - Table view data source
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "Section (section)"
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell=UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "mycell")
var nameLabel:UILabel = UILabel(frame: CGRect(x: 50,y: 5,width: 200,height: 30))
nameLabel.text="Title\(indexPath.row)"
nameLabel.textColor=UIColor.brownColor()
nameLabel.font=UIFont.boldSystemFontOfSize(15)
nameLabel.textAlignment=NSTextAlignment.Left
cell.contentView.addSubview(nameLabel)
var imageView:UIImageView=UIImageView(frame: CGRect(x: 5,y: 2,width: 40,height: 40))
imageView.backgroundColor=UIColor.purpleColor()
imageView.layer.masksToBounds=true
imageView.layer.cornerRadius=imageView.frame.width/2
cell.contentView.addSubview(imageView)
return cell
}
}
I wrote this in Xcode 6 (Swift) but it says "Type 'FirstViewController' does not conform to protocol 'UITableViewDataSource'" and won't let me build the program. Please help?
import UIKit
class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//UIViewTableDataSource
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int{
return taskMGR.tasks.count
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) ->
UITableViewCell!{
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier:
"test")
cell.textLabel?.text = taskMGR.tasks[indexPath.row].name
cell.detailTextLabel?.text = taskMGR.tasks[indexPath.row].desc
return cell
}
}
As I wrote in the comments you might as well change the class to a UITableViewController subclass as it is basically the same as UIViewController + UITableViewDelegate + UITableViewDataSource (with a little bit of extra functionality included if you want it). It also has a UITableView property included "out of the box".
You will then end up with the following class:
class FirstViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//UIViewTableDataSource
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return taskMGR.tasks.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier:"test")
cell.textLabel?.text = taskMGR.tasks[indexPath.row].name // You can remove ? when updating to XCode 6.1 / Swift 1.1
cell.detailTextLabel?.text = taskMGR.tasks[indexPath.row].desc
return cell
}
}
I rewrote your class to work. I deleted a couple of variables I did not need, but you can add them back. Key was to delete 'UITableViewDataSource' (you do not conform to this) and to unwrap the optional cell the way you wrote it. I prefer not to construct the cell that way, but that is another discussion. If you still have issues let me know.
import UIKit
class FirstViewController: UIViewController, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//UIViewTableDataSource
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int{
return 1
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) ->
UITableViewCell!{
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier:
"test")!
return cell
}
}
Started practice swift. In singleViewController I am trying to make a UITableView. In storyboard I set the datasource and delegate. Here I am getting the error * 'ViewController' does not conform to protocol 'UITableViewDataSource' *
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
func numberOfSectionsInTableView(tableView: UITableView!) -> Int
{
return 20
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
{
let cell:UITableViewCell=UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "mycell")
cell.textLabel.text="row#\(indexPath.row)"
cell.detailTextLabel.text="subtitle#\(indexPath.row)"
return cell
}
You should implement all the required methods before the last }, but you have written them outside of the UIViewController. Also, you need to change the func for number of lines.
the suggested edit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView:UITableView!, numberOfRowsInSection section:Int) -> Int
{
return 20
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
{
let cell:UITableViewCell=UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "mycell")
cell.textLabel.text="row#\(indexPath.row)"
cell.detailTextLabel.text="subtitle#\(indexPath.row)"
return cell
}
}
Try removing the ! on your func. That did the job for me
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell:UITableViewCell=UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "mycell")
cell.textLabel.text="row#\(indexPath.row)"
cell.detailTextLabel.text="subtitle#\(indexPath.row)"
return cell
}
You need to implement all the required methods of UITableViewDataSource in order to get rid of that error.
Basically... you're missing:
func tableView(tableView:UITableView!, numberOfRowsInSection section:Int) -> Int {
//return XX
}
I had the same problem, things would workout rather easily in Objective-C, probably because we are more familiar with it at the moment, but in this case, swift is very new, therefore, the its error notifications are rather vague.
While I was implementing the UITableView based application, and I ran into this problem. I opened up the implementation file for UITableView by pressing command and clicking on UITableView. In implementation file, we can clearly see that two functions are mandatory to implement,
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
I arrived at this post and started to put things together while keeping my meager knowledge of objective-C programming in mind. Reason for the error being that a table view is defined by two elements, first the section and rows in a section, and second the tableview cells. By default there is at least one section in the table view, but we need conformance about number of rows in a section. Secondly, we need to know which cell are we going to present in a particular row in a section. Regardless,even if we are using default UITableViewCell, we still need an identifier to access it in order to set its subviews or properties.
I hope it was helpful, A bit soft criticism will be appreciated since I am myself very new to Swift :)
The following code didn't work for me on iOS 8.1. in XCode 6.1.1. This code works:
import UIKit
class ViewController : UIViewController,UITableViewDelegate,UITableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
//currently only a testing number
return 25
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var cell:UITableViewCell=UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "mycell")
cell.textLabel?.text = "row#\(indexPath.row)"
cell.detailTextLabel?.text = "subtitle#\(indexPath.row)"
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I had just faced the same problem in Swift.
You should realize all the functions for the UITableViewDataSource in the class, which means the following functions should be realized:
func numberOfSectionsInTableView(tableView: UITableView) -> Int{}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {}
I'm not sure whether missing the function for numberOfSectionsInTableView works for you or not. For me, I have to realize it in my class.
Just Add these two methods then that error will be resolved[XCode8 Swift3]
first method :
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
}
Second Method :
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
}
Take out all the optionals for tableview and NSIndexpath for the latest Xcode 6.1.1 GM_Seed
Just a suggestion to improve readability, you can separate your protocols using extension, like this:
class ViewController: UIViewController {
// Your lifecycle code here
}
extension ViewController: UITableDataSource {
func tableView(tableView:UITableView!, numberOfRowsInSection section:Int) -> Int {
return 20
}
}
extension ViewController: UITableViewDelegate {
...
}
This is probably caused by a typo or wrong styling on the method name. I used to cmd + left click on UITableView and copy & paste method names on my UIViewController; which won't work on Swift.
Instead, type func tableView, look for the desired method on the list and let auto complete do its job.
This is a common warning which means that " you haven't implemented the required methods of the protocol yet"
A view object on the storyboard may need a datasource. For example, TableView needs a datasource and usually, View Controller acts as one.
So Table View expects the ViewController to contain the methods which return the 'must have' information for the table view.
Table view needs to know the number of sections, number of rows in each section etc..
Unless all the required information is returned by the datasource object, the warning will persist.
Change the syntax of "UITableViewDataSource" protocol required methods as per new swift 3 documentation:
internal func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
internal func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
This has worked for me while compiling with swift 3 compiler
The answer of Ankit worked for me in Xcode 8 for Swift 2.3. Here’s the new syntax.
extension ViewController: UITableViewDataSource {
internal func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return 1
}
internal func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//return cell
}
}
Add these methods
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
}
Copy the code below under the ViewController class and specify the number of rows you want (in the 1st section) and define the content of each cell (in 2nd function)
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1 //no. of rows in the section
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: <#T##UITableViewCellStyle#>, reuseIdentifier: <#T##String?#>)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
with some edits suggested by auto complete, from the above answer by #MB_iOSDeveloper on swift 3, Xcode 8.3.2, this code works for me:
class MenuViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
//currently only a testing number
return 25
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
var cell:UITableViewCell=UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "mycell")
cell.textLabel?.text = "row#\(indexPath.row)"
cell.detailTextLabel?.text = "subtitle#\(indexPath.row)"
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
In general, a protocol has optional and required methods. For example, UISearchBarDelegate and UITableViewDelegate are the cases that you can declare to conform to a protocol without implementing any of their methods. But it does not work fine for UITableViewDataSource.
In the official documentation, Protocol "UITableViewDataSource" -> Symbols -> Configuring a Table View, the methods:
func tableView(UITableView, cellForRowAt: IndexPath) and func tableView(UITableView, numberOfRowsInSection: Int) shown with bold Required key word.
just remove the viewDidLoad()
and Build and add viewDidLoad()
everything is ok