Please see my code below, runs in Xcode 6.1 IOS 8 failed, it report error below:
Type "ViewController" doesn't conform to Protocol "UITableViewDataSource"
Could anyone help to have a look what is the problem is? Thank you!
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var tableView = UITableView()
var items: NSMutableArray = ["row 0","row 1","row 2","row 3","row 4"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView.frame = CGRectMake(10, 10, 300, 530)
tableView.backgroundColor = UIColor(red: 90/255, green: 31/255, blue: 10/255, alpha: 0.2)
// tableView.style = UITableViewStyle.Grouped
tableView.rowHeight = 50
tableView.separatorColor = UIColor.blueColor()
tableView.separatorStyle = UITableViewCellSeparatorStyle.SingleLine
//self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
// tableView.delegate = self
// tableView.dataSource = self
self.view.addSubview(tableView)
}
//UITableViewDataSource
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
//println("Hello \(indexPath.row)")
var cell = tableView.dequeueReusableCellWithIdentifier("my cell id") as? UITableViewCell
if (cell == nil) {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "my cell id")
}
//cell.textLabel?.text = listOfViewControllers[indexPath.row]
//cell!.textLabel?.text = items[indexPath.row] as String
//var s = items.objectAtIndex(indexPath.row) as? String
var s = items.objectAtIndex(indexPath.row) as String
cell!.textLabel?.text = s
return cell
}
//UITableViewDelegate
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Issue is with this method signature, it is not similar to the one defined in the UITableViewDataSource
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
Change that to:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
Related
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 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've created UITableView programmatically, but it doesn't show any separators. When I run the project I can see on Debug View Hierarchy that it exists, but i cannot understand why i cannot see it on simulator? Any of you knows what I'm missing or what is wrong with my code?
I'll really appreciate your help.
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
//🔵 Proerties
var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView = UITableView(frame: view.bounds)
tableView.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
tableView.dataSource = self
tableView.delegate = self
tableView.rowHeight = 100
tableView.separatorColor = UIColor.redColor()
tableView.separatorStyle = .SingleLine
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
view.addSubview(tableView)
}
// 🔵 UITableViewDataSource
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
let row = indexPath.row
cell.textLabel?.text = String(row)
return cell
}
// 🔵 UITableViewDelegate
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.backgroundColor = UIColor.cyanColor()
}
}
I would like to add a picker view at the footer of the app when I tap the cell and change the Detail label with the picker view data. I would like to do the same think with the DatePicker, but only in one cell ( the one named Service appt. Date).
This is my code:
import UIKit
class Service2Appointment: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var TableView: UITableView!
#IBOutlet weak var pickerView: UIPickerView!
let FormName = ["State","City","Vehicle Reg Number","Location","Current Kms","Service appt. Date","Service appt. Type","Pick-up Vehicle","Discount Code","Service Notes"]
let textCellIdentifier = "TextCell"
override func viewDidLoad() {
super.viewDidLoad()
pickerView.hidden = true
TableView.delegate = self
TableView.dataSource = self
self.TableView.rowHeight = 70
TableView.backgroundView = UIImageView(image: UIImage(named: "background.png"))
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: UITextFieldDelegate Methods
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return FormName.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = TableView.dequeueReusableCellWithIdentifier(FormName[indexPath.row], forIndexPath: indexPath) as! UITableViewCell
if (indexPath.row % 2 == 0) {
cell.backgroundColor = UIColor.clearColor()
}else{
cell.backgroundColor = UIColor.clearColor()
cell.textLabel?.backgroundColor = UIColor.whiteColor().colorWithAlphaComponent(0.0)
}
let row = indexPath.row
cell.detailTextLabel?.text = FormName[row]
cell.textLabel?.text = FormName[row]
cell.textLabel?.textColor = UIColor.whiteColor()
return cell
}
// MARK: UITableViewDelegate Methods
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
TableView.deselectRowAtIndexPath(indexPath, animated: true)
let row = indexPath.row
println(FormName[row])
}
}
I have referred to this question, and tried to implement the various answers. I'm doing something dumb, as cellForRow is not being called, and I'm just getting a blank tableView. Are there other data source or delegate methods that I must override?
Thanks
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//tableView.delegate = self
//tableView.dataSource = self
tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell")
//tableView.registerClass(MyTableViewCell.self, forCellReuseIdentifier: "Cell")
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
println("cellForRowAtIndexPath")
println()
//variable type is inferred
var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as? UITableViewCell
if !cell {
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "CELL")
}
cell!.textLabel.text = "Text Label"
cell!.detailTextLabel.text = "Detail Text Label"
return cell
}
}
UPDATE - The following appears to work.. Thanks for the help!!
class ViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//tableView.delegate = self
//tableView.dataSource = self
tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell")
//tableView.registerClass(MyTableViewCell.self, forCellReuseIdentifier: "Cell")
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
println("cellForRowAtIndexPath")
println()
//variable type is inferred
var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as? UITableViewCell
if !cell {
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "CELL")
}
cell!.textLabel.text = "Text Label"
cell!.detailTextLabel.text = "Detail Text Label"
return cell
}
}
Here is working code. No need to register cell in -viewDidLoad(). Also UITableView is added as subview in Storyboard.
If someone has this kind of requirement.
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as UITableViewCell?
if (cell == nil) {
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "CELL")
}
cell?.textLabel?.text = NSString(format: "%d", indexPath.row) as String
return cell!
}
}
You need to connect Delegate DataSource of TableView, both are connected with the tableview then can only NumberOfRowsInSection and CellForRowAtIndexpath called.