So, I'm getting a 'Type ViewController does not conform to protocol UITableViewDataSource' error in Xcode. I've implemented the required functions:
cellForRowAtIndexPath
numberOfRowsInSection
I've even made sure I've told Xcode how many sections there are (which is not required). This is a Single View Application and I have ensured my references are setup correctly in Storyboard. So my Outlets are my view and my table view. My Referencing Outlets are set for dataSource and delegate to be my Table View.
Here's the code.
ViewController.swift
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var items: [String] = ["We", "Dislike", "Swift", "Very", "Much", "Right", "Now"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.delegate = self
tableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int{
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath:indexPath) as UITableViewCell
cell.textLabel?.text = self.items[indexPath.row]
return cell
}
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
println("You selected cell #\(indexPath.row)!")
}
}
EDIT: Also, I know that I shouldn't need the tableView.delegate and tableView.dataSource as I have assigned them in the Storyboard but I thought I'd include them to make sure you all know that I know to have them set.
UITableViewDataSource protocol has changed a little bit. Try:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
Your tableView(tableView:cellForRowAtIndexPath) signature is wrong - it should be:
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell {
let cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath:indexPath) as UITableViewCell
cell.textLabel?.text = self.items[indexPath.row]
return cell
}
Note that it doesn't return an optional value (i.e., no ! suffix) any more.
Related
I wanted to give a go at swift, and looked at several tutorials. I tried to implement a TableView.
Here is my code :
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var items: [String] = ["lol1", "lol2", "lol3"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1;
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: "cell")!
cell.textLabel?.text = self.items[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
print("You selected cell #\(items[indexPath.row])!")
}
}
MY IBOutlet is connect to the tableview I inserted in the storyboard.
When I run it, I have a TableView, but it's missing contents.
From what I gathered through some (more or less outdated) tutorials, I shouldn't have anything more to do, what am I missing ?
Where are you set dataSource and Deleagte methods of TableView?
use this code
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.tableView.dataSource = self
self.tableView.delegate = self
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
2 possible reasons:
If the cell is designed as prototype cell you must not register the cell.
dataSource and delegate of the table view must be connected to the controller in Interface Builder or set in code.
I have created a slide out menu using Swift. I have done this many times before, but when I created it today, I get this error (see screenshot). It could just be a simple mistake I have made.
Here is the code, that I think is causing the problem:
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell:UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("Cell")! as UITableViewCell
if cell == nil{
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell!.backgroundColor = UIColor.clearColor()
cell!.textLabel!.textColor = UIColor.darkTextColor()
let selectedView:UIView = UIView(frame: CGRect(x: 0, y: 0, width: cell!.frame.size.width, height: cell!.frame.size.height))
selectedView.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.3)
cell!.selectedBackgroundView = selectedView
}
cell!.textLabel!.text = tableData[indexPath.row]
return cell
}
Screenshot:
UPDATE: I have tried removing override
Hope someone can help!
The method does not override any method of the superclass because the signature is wrong.
The correct signature is
override func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
All parameters are non-optional types.
And use also the recommended method
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier,
forIndexPath: indexPath)
which also returns always a non-optional type
Make sure that your class implements UITableViewDelegate and UITableViewDataSource.
class MyController: UIViewController, UITableViewDelegate, UITableViewDataSource {
// All your methods here
}
You won't need override keyword unless any other superclass already implements those methods.
See this works for me
Just confirm UITableViewDelegate and UITableViewDataSource
Implement required methods
import UIKit
class ListViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let containArray = ["One","two","three","four","five"]
// MARK: - View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: Table view data source and delegate methods
//Number of rows
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return containArray.count
}
//Prepare Custom Cell
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let identifier = "simpleTextCell"
var cell: SimpleTextCell! = tableView.dequeueReusableCellWithIdentifier(identifier) as? SimpleTextCell
if cell == nil {
tableView.registerNib(UINib(nibName: "SimpleTextCell", bundle: nil), forCellReuseIdentifier: identifier)
cell = tableView.dequeueReusableCellWithIdentifier(identifier) as? SimpleTextCell
}
let dayName = containArray[indexPath.row]
cell.lblProductName.text = dayName
return cell
}
//Handle click
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("productListSegue", sender: self)
}
}
Try to removing "!", declaration for this function is:
func tableView(_ tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
and make sure you have set delegate and datasource of tableview to "self"
I have embedded UITabbar in UIViewController and then I put some UITabbarItems in my UITabbar. I also created another UIViewController with UITableView embedded in it.
I have linked one of the UITabbarItem with this newly created UIViewController(with UITableView in it).
When I run the program and tap on that UITabbarItem it shows a table view but when I select any row of table, the data displaying in UITableView disappears.
I then debug the code and found that didSelectRowAtIndexPath method didn't call.
I searched on the internet and find this but cannot understand it well.
I tried by implementing both types of tableViews (UITableViewController,UIViewController with UITableView in it) but still same problem.
I am stuck here. Anyone please help me. How to get resolve this issue.
I will be very Thankful to you.
Here is my swift code
import UIKit
class DashboardViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var selectedIndexPathForCheckMark:NSIndexPath?
var items: [String] = ["We", "Heart", "Swift"]
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("MyCell")!UITableViewCell
cell.textLabel?.text = self.items[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("You selected cell #\(indexPath.row)!")
selectedIndexPathForCheckMark = indexPath
tableView.reloadData()
}
here are its snapshots
Second UITabbarItem from right implements UITableView
Follow Steps:
1. Take A view controller and add tableview.
2. set outlet with MytabelView
3. set Datasource and delegate of tableview to ViewController
4. and put the following code in ViewController class
5. Take a custom tableview cell with name MyCell having cell identifier "MyCellid"
6. Create swift file with name MyCell, make it subclass of UITableViewCell
7. Choose custom cell and assign it class to MyCell.
I think Its done
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
#IBOutlet weak var MytableView: UITableView!
var items: [String] = ["We", "Heart", "Swift"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.MytableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "MyCellid")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.MytableView.dequeueReusableCellWithIdentifier("MyCellid")! as UITableViewCell
cell.textLabel?.text = self.items[indexPath.row]
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("You selected cell #\(indexPath.row)!")
}
}
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.
Here is my Code , Compiler is still showing error although I wrote implementation of both methods
Please tell why
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.
}
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
}
}
Here is screenshot of Xcode
You have probably written this code in a previous version of Xcode. The correct signature for the 2 methods has changed, and it's now:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
The tableView parameter is no longer an optional.