Swift cellForRowAtIndexPath definition conflicts with previous value - ios

Below is the code for my tableView, I have an error on the cellForRowAtIndexPath function declaration that says definition conflicts with previous value. A previous stack overflow question has the solution to make the function return UITableViewCell as an optional value but this does not fix the error for me. I also have an error that says viewController does not conform to protocol UITableViewDataSource, but I assume this is because of the error on the cellForRowAtIndexPath method.
I have similar code for a tableView that works, but it was written about a month ago before I updated Xcode. Maybe a recent change in swift is causing the error?
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int
{
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell? {
let cellIdentifier = "tableViewCell"
let newCell : TableViewCell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as! TableViewCell
newCell.heading.text = names[indexPath.row]
return newCell
}

Try placing your datasource methods in a class extension like this:
extension yourViewController: UITableViewDataSource {
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { // cellForRow stuff
}
}

If this is in a UITableViewController, you need to add override to the method:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell

Related

How to add animation on tableView Swift

I want to add animation when UITableView load cells (From top to Bottom) But getting no idea about this, please someone help me.
Below added a simple table view delegate methode with an array(arrHeader).
Thanks in advance
let arrHeader = ["City1", "City2", "City3"]
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrHeader.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell")
cell?.textLabel?.text = arrSubHeader[indexPath.row]
return cell!
}
Put your animation code in this UItableView delegate method:
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
//TODO: animation code
}
this delegate method is called every time a new or old cell is going to be displayed on the iPhone/iPad screen.
So if you try something in this block with the cells it will reflect on them.
optional func tableView(_ tableView: UITableView,
didEndDisplaying cell: UITableViewCell,
forRowAt indexPath: IndexPath) { }
this method gets called after a cell is being displayed.
Here is the github link for the Example:
Visit: https://github.com/subhajitregor/TableCellCardDropAnimationExample

iOS Swift didSelectRowAtIndexPath not working

I want to execute a single line of code when the user selects a cell in my TableView. At runtime, my TableView populates with data okay, and the cells are indeed clickable/selectable. But, when a cell is selected, the 'didSelectRowAtIndexPath method is skipped/not called. I'm new to Swift, so maybe I'm overlooking something very simple. The structure of my code is as follows:
import UIKit
class TopicsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
//Number of Sections:
func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 2 }
//Number of Rows in Each Section:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) ->Int { return 3 }
//Contents of Each Cell:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell()
cell.textLabel?.text = "Data"
}
//Code below is skipped/ignored at runtime, no matter what I try:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("Hello!")
}
Note: I am not using a gesture recognizer (other threads on this subject suggest a gesture controller could be the culprit)
Did you assign the "delegate" of the tableview?

Does not call didSelectRowAtIndexPath

Basically, my table is displaying properly as what I would want it to be. However, when I click on my cell, it doesn't goes into my didSelectRowAtIndexPath method.
The below screenshot also doesn't show any preloaded didSelectRowAtIndexPath method.
My codes are as follows:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return personList.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let myCell = stockTableView.dequeueReusableCellWithIdentifier("personCell", forIndexPath: indexPath) as UITableViewCell
myCell.textLabel?.text = personList[indexPath.row].personName
myCell.detailTextLabel?.text = personList[indexPath.row].GetPersonDescription()
return myCell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
let myCell = stockTableView.dequeueReusableCellWithIdentifier("personCell", forIndexPath: indexPath) as UITableViewCell
let selectedCell = myCell.textLabel?.text
}
EDIT: After researching, I realised that I've not set my UITableViewDelegate protocol. I tried to find online but can't find any solution. Could someone help me with this?
// Set the UITableViewDataSource and UITableViewDelegate for your class
class YourClass: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.YourTableName.registerClass(UITableViewCell.self, forCellReuseIdentifier: "TotalsCell")
// Delegate and DataSource for your TableView
YourTableName.dataSource = self
YourTableName.delegate = self
}
}

Type "someViewContoller" does not conform to protocol "UITablViewDataSource"

I am really new to the whole Swift thing and also programming in general. I have researched everywhere but couldn't find an answer for the error that I got. Please help me :)
import Foundation
import UIKit
class TümÜrünlerViewController : UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tümÜrünlerTableView: UITableView!
#IBAction func cancelTapped(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
var ürünler = ["Havalı", "Daha Havalı", "Eheheh"]
var ürün = "Balık"
func TableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var cell = UITableViewCell()
cell.textLabel!.text = self.ürünler[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.ürün = self.ürünler[indexPath.row]
self.performSegueWithIdentifier("başlıklardanÖzeleSegue", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tümÜrünlerTableView.dataSource = self
self.tümÜrünlerTableView.delegate = self
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var detailViewController = segue.destinationViewController as BaşlıklarViewController
detailViewController.ürün = self.ürün
if self.ürün == "Havalı" {
detailViewController.label = "anan"
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) ->Int {
return self.ürünler.count
}
}
Here is my code but I am getting the error when I try to insert UITableViewDataSource. I tried everything that the forums said but it docent seem to work for me :(
My guess:
Let us look at this method. T needs to be decapitalized. tableView not TableView
func TableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var cell = UITableViewCell()
cell.textLabel!.text = self.ürünler[indexPath.row]
return cell
}
It's a very simple mistake - the UITableViewDataSource requires that 2 methods are implemented:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
but you've just made a typo in the 2nd one:
func TableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
^
the method name should start in lowercase: tableView(...)
You have a capital T on your cellForRowAtIndexPath function. It should read:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var cell = UITableViewCell()
cell.textLabel!.text = self.ürünler[indexPath.row]
return cell
}
Reason behind error is that, you are not calling datasource required method in correct order. Correct order of calling is :
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
Always, make sure you call numberOfRowsInSection before cellForRowAtIndexPath.

Conform to protocol in ViewController, in Swift

Trying to conform to UITableViewDataSource and UITableViewDelegate inside a Swift UIViewController subclass.
class GameList: UIViewController {
var aTableView:UITableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
aTableView.delegate = self
aTableView.dataSource = self
self.view.addSubview(aTableView)
//errors on both lines for not conforming
}
}
Docs say you should conform on the class line after the : but that's usually where the superclass goes. Another : doesn't work. Using a comma separated list after the superclass also doesn't work
EDIT:
Also must adopt all required methods of each protocol, which I wasn't initially doing.
You use a comma:
class GameList: UIViewController, UITableViewDelegate, UITableViewDataSource {
// ...
}
But realize that the super class must be the first item in the comma separated list.
If you do not adopt all of the required methods of the protocol there will be a compiler error. You must get all of the required methods!
As XCode6-Beta7 releases,
I noticed the protocol method of UITableViewDataSource changed a little bit and sounded the same conform to protocol error which worked fine in beta6.
These are the required methods to be implemented according to the UITableViewDataSource protocol:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { // insert code}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // insert code
}
You might want to re-check the difference or re-implement the delegate method that you thought you just implement.
You must implement two require methods here:
func tableView(tableView:UITableView!, numberOfRowsInSection section:Int) -> Int {
return 10
}
func tableView(tableView:UITableView!, cellForRowAtIndexPath indexPath:NSIndexPath!) -> UITableViewCell! {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "MyTestCell")
cell.text = "Row #\(indexPath.row)"
cell.detailTextLabel.text = "Subtitle #\(indexPath.row)"
return cell
}
Also, it is important to copy all the non optional functions from the Delegate class. Cmd + Click on the UITableViewDatasource
and copy those two definitions as is.
For me in beta7, the UITableViewDatasource has
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
My implementation:
var items = ["Apple", "Pear", "Banana"]
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Default")
cell.textLabel?.text = items[indexPath.row]
cell.detailTextLabel?.text = "Test"
return cell
}
Usee These methods:
There is change in Data source methods-
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
protocol UITableViewDataSource : NSObjectProtocol {
****func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell****
optional func numberOfSectionsInTableView(tableView: UITableView) -> Int // Default is 1 if not implemented
optional func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? // fixed font style. use custom view (UILabel) if you want something different
optional func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String?
// Editing
// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.
optional func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool
// Moving/reordering
// Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath:
optional func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool
// Index
optional func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]! // return list of section titles to display in section index view (e.g. "ABCD...Z#")
optional func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int // tell table which section corresponds to section title/index (e.g. "B",1))
// Data manipulation - insert and delete support
// After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change
// Not called for edit actions using UITableViewRowAction - the action's handler will be invoked instead
optional func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
// Data manipulation - reorder / moving support
optional func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath)
}
Ur code will works!!
This question is already answered but just want to make things a bit more Swifty.
Instead of writing protocols in UITableViewDelegate, UITableViewDataSource you can divide them using extensions this will help in organising the code. Adding protocol conformance is described in this page
for the above question, this can be confirmed to protocol using extension:
class GameList: UIViewController {
var aTableView:UITableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
aTableView.delegate = self
aTableView.dataSource = self
self.view.addSubview(aTableView)
}
}
extension GameList: UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return list.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath)
return cell
}
}
extension GameList: UITableViewDelegate{
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Row Clicked at \(indexPath.row)")
}
}

Resources