I'm learning Swift and, coding some lines, an error appear on the screen showing: Type JVViewController (class name) does not conform to protocol 'UITableViewDataSource'. I don't know why this appear in my file if I did exactly the same in other apps and I never did this kind of problem.
Please, let me know how to solve this situation.
Thanks!
If a class does not conform with a protocol, it means you need to implement some protocol methods. In case on the UITableViewDataSource, is required to implement the follow methods:
It defines the quantity of tableViewCell you will show on your tableView
tableView(_:numberOfRowsInSection:)
It defines the settings of each tableViewCell
tableView(_:cellForRowAtIndexPath:)
Maybe you forgot to implement one or this two dataSource methods.
E.g.:
class JVViewController : UIViewController, UITableViewDelegate, UITableViewDataSource {
...
var collectionItems = ["One", "Two", "Three"]
...
//Quantity of rows
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.collectionItems.count;
}
//Row settings
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel?.text = self.collectionItems[indexPath.row]
return cell
}
...
}
You can find out more in Apple documentation: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDataSource_Protocol/
Related
I'm playing around with the UITableView in XCode 10.2.1 with Swift 5. According to the Apple Developer docs, adopting the UITableViewDataSource is the most straightforward way to populate a UITableView with dynamic data.
So I copied the necessary methods to override into a custom class:
import Foundation
import UIKit
class MyDataSource : NSObject, UITableViewDataSource {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Fetch a cell of the appropriate type.
let cell = tableView.dequeueReusableCell(withIdentifier: "cellTypeIdentifier", for: indexPath)
// Configure the cell’s contents.
cell.textLabel!.text = "Cell text"
return cell
}
}
But my code won't compile. All I get is a "Method does not override any method from its superclass" error. What? I even did used the autocomplete feature from XCode and it generated the stubs for me, yet I still cannot build my project. What is the solution?
Your class' superclass is NSObject which does not have those table view data source methods to override in a subclass. I believe that is what that compiler is saying.
I think if you take off the override keyword on those function declarations that could help.
I have a CoreData entity which I need to populate the value of each objects into a table view cell. In the storyboard, I can add rows and change the style of my cells individually, but in this case I'm dealing with cells based on my number of objects and I have to programmatically insert rows and change the cell style.
I'm guessing that I need a foreach loop with the code to insert rows programmatically. Does anyone know how to achieve this?
You have to implement UITableViewDataSource. See the API Reference for more information.
When using Core Data with UITableViews you might also want to take a look at NSFetchedResultsController.
You need to use UITableViewDataSource methods. Add the dataSource protocol to your class and conform to it. The method you are looking for is:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
You probably will also want to conform to UITableViewDelegate protocol.
Do something like this:
class MyClass: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//Do your thing
}
//Conform to rest of the delegate and datasource methods too. Click on UITableViewDataSource to see the documentation
You need to implement override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int and return your objects array's count, then set a reuse identifier for the cell and add the code:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") //replace "Cell" with your identifier
cell.textLabel = yourTitleArray[indexPath.row]
cell.detailTextLabel = yourSubtitleArray[indexPath.row]
return cell!
}
Don't forget to replace yourTitleArray and yourSubtitleArray with your arrays.
I'm just starting with Swift and xCode, and currently messing around with UITableView, I can't manage to just write 'test' into a table.
I created a UITableViewController in the Storyboard, specified a custom class for it (my swift file below), filled in 'ClientCell' as a reuse identifier of the cell and the code is as follows:
class TableViewController: UITableViewController {
#IBOutlet var clientTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
clientTable.dataSource = self.dataSource;
clientTable.delegate = self;
}
func numberOfRowsInSection(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("ClientCell", forIndexPath: indexPath) as! CustomTableViewCell
cell.tableLabel.text = "test"
return cell
}
}
In the storyboard, I added a 'UILabel' into the prototype cell, and created an outlet for it named 'tableLabel' in the CustomTableViewCell.swift.
I confused by all the side-things I've to consider when doing something as simple as this.
When I run it, the simulator just shows a table with a lot of horizontal lines, but nowhere it says 'test'.
You haven't used the numberOfRowsInSection method.....
Additionally you also need to set the table view's data source and delegate to be the class you are writing these methods in (in case you haven't).
At a bare minimum you need this:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1 // this should really be from your data source
}
If you create a UITableViewController subclass in Xcode the template will have commented-out versions of all the methods you likely will want to fill out.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
print("WTF is this getting hit...")
let Cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell
Cell.textLabel?.text = self.funlists[indexPath.row]
print("This better be getting hit")
return Cell;
}
for some reason this method isn't getting called.
i have set the following
uiTableView.delegate=self
uiTableView.dataSource=self
uiTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
and I have also included,
class viewUniversityList: UIViewController, UITableViewDelegate, UITableViewDataSource {
There might be several reason for this. Some of them are :
If you are using tableView in your ViewController file, then you should add the UITableViewDelegate and UITableViewDelegate delegates, like this :
class ViewController: UIViewController,UITableViewDelegate, UITableViewDelegate { ... }
If you have created a tableView in code then you should do the
following :
tableView.delegate = self
tableView.dataSource = self
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "reuseIdentifier")
If that's all done, or you have create UITableView through storyboard with a separate class which is a subClass of UITableView, then you definitely need to define the
following methods :
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {...}
~ func numberOfSectionsInTableView(tableView: UITableView) -> Int {...} is optional as suggested by #rmaddy, but it's a good practice to define it.
delegate property is not set on the tableView?
also tableView:numberOfRowsInSection: should be implemented
you have to set your delegates and declare that you use those protocols
in file.m in didLoad
_table.delegate = self;
_table.dataSource = self;
in file.h when you declare the interface you have to add these protocols UITableViewDelegate and UITableViewDataSource
Xcode will tell you which methods you must implement to respect the protocol.
Numerous tutorials I've been through say the only code I need to display the array I want it to is:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var chatListTableView: UITableView!
var friends = ["Anthony", "Antonio", "Andy"]
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return friends.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "ChatListCell")
cell.textLabel.text = self.friends[indexPath.row]
return cell
}
}
However, when I run the app, the tableView is still blank. What am I doing wrong? I feel that I am missing something.
All I want to do is display the array in the tableView.
Check if the ViewController is the datasource and delegate of the tableview
As Aci says in his answer, you have to set the data source and delegate of the table view to your view controller. The easiest way to do that is in Interface Builder.