I have a UITableView placed on a view controller in storyboard. I set the datasource and delegate for the table view to self and I specified the UITableViewDelegate and UITableViewDatasource in the view controller class declaration. All of the datasource functions work properly. In other words, when cellForRowAtIndexPath is called, it executes fine.
The problem is that the delegate methods for the tableView are not executing. I verified this by placing a breakpoint at the beginning of
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
I also noticed that the keyword optional is specified to be prefixed for the above delegate method as such:
optional func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
However, if I add the optional keyword to the beginning of the function, I get the error optional can only be applied to protocol members.
I have no idea why my heightForRowAtIndexPath is not getting called. Can anyone help me on this? Thanks in advance.
Related
I have a table view controller that needs to be updated through a delegate call. I have set the datasource and delegate and on initial load of the tableview, all works as expected. I have a delegate method that gets called after a datasource update. The delegate calls a refresh method in the table view controller class which calls .reloadData()
When reloadData is called, numberOfRowsInSection is called and accurately returns the number of rows, however cellForRowAtIndexPath never gets called.
In this particular case, numberOfRowsInSection returns 2, therefore cellForRowAtIndexPath should be called twice but it's called zero times.
On initial load everything is fine. It's only when reloadData is called taht cellForRowAtIndexPath is ignored. I have done this same thing many times in Obj-C without any weirdness. Are there any known issues with this in Swift?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(LayerMenuCell.reuseId) as! LayerMenuCell
// ....
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(layerEntries?.count)
return (layerEntries?.count)!
}
func refresh() {
self.layersTableView.reloadData()
}
Thanks!
Try setting the delegate and dataSource of your UITableView:
myTable.delegate = self
myTable.dataSource = self
As specified in the Documentation:
A functioning table view requires three table view data source
methods.
func numberOfSectionsInTableView(tableView: UITableView) -> Int
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
MAake sure you implement the above three delegate methods and they return some values other than nil or 0.
There is a chance that cell height could be 0/ table height is 0 in both the cases cell for row method will not get called.
Also make sure you set the delegate properly and call the reloadData method on main thread. More on here
Things you need to check when Tableview is not working as expected:
1. Setting the delegate and datasource through storyboard or by code.
self.tableView.delegate = self
self.tableView.dataSource = self
2.check if tableView in storyboard is connected to tableView outlet.
3.check numberOfRowsInSection and numberOfSectionsInTableView returning the correct values.
4.check if the methods is written properly.
5.add the delegate and datasource after UIViewController.
<UITableViewDelegate , UITableViewDataSource>
this will help you if you are missing any thing.
I am trying to create custom row action for my tableview program.
In order to do that I learned that I have to implement the table view function with editActionsForRowAtIndexPath. But Xcode says there is no method to override in the superclass.
Below is the code in question
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath:
NSIndexPath) -> [AnyObject] {}
i am fresher and i am doing my app in swift language and i want to know that what is the difference between
func cellForRowAtIndexPath(indexPath: NSIndexPath) -> UITableViewCell?
and
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell/
delegate methods in UITableView?
As a one line answer to the question,
The first method
func cellForRowAtIndexPath(indexPath: NSIndexPath) -> UITableViewCell?
is not tableView delegate method. It an instance method in UITableView Class. Which is used to get a cell from tableView instance by passing indexPath as parameter. So you will be using this method on a tableView instance.
The second method
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
is the datasource method of UITableView that is used to populate tableview cells. This method will be implemented in the datasource/delegate class.
func cellForRowAtIndexPath(indexPath: NSIndexPath) -> UITableViewCell? is a UITableView method, it is used to get a cell at a given time when the tableview is defined. For instance, it can be used to check is a cell is visible. If it is not visible this method will return nil.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell is a UITableViewDataSource method, it is used to define all the cells of the tableview, so that it can know what to display.
The first method
func cellForRowAtIndexPath(indexPath: NSIndexPath) -> UITableViewCell?
It is an instance method in UITableView Class. And it is used to get a cell from tableView instance by passing indexPath as parameter .
and the second one
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
is the datasource method of UITableView and it is one of the require method in UITableView.
Thank you.
I'm trying to call cellForRowAtIndexPath from within heightForRowAtIndexPath in order to assign a height based on the cell's type (I'm subclassing UITableViewCell). Trivial, right? Well, calling it there causes a loop. I can't quite seem to figure out why that would be. Placing breakpoints in both methods doesn't yield anything—the delegate method cellForRowAtIndexPath never actually gets called. Take a look:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
switch indexPath.row {
case 0:
return SubclassCellTypeOne()
default:
return SubclassCellTypeTwo()
}
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
// Calling cellForRowAtIndexPath here causes a loop
let cell = tableView.cellForRowAtIndexPath(indexPath)!
if cell is SubclassCellTypeOne {
return UITableViewAutomaticDimension
} else {
return 100
}
}
Any idea why that's happening? And any suggestions on how to get around it? Thanks!
When a reference to a cell is made via a UITableView, (usually by iOS, when loading your view), iOS calls the methods in its lifecycle - e.g., heightForRowAtIndexPath, editingStyleForRowAtIndexPath to work out how to display it etc.
So your source of an infinite loop is that you make a reference to a cell, inside a method that is called when a reference to a cell is made ;)
To fix this, you should reference back to your data source, instead of asking the cell directly about itself. If you have a class set up as a data collection, this is easy.
Yep, you shouldn't call cellForRow inside heightForRow.
In heightForRow you have the indexPath variable. You can use indexPath.row to determine the class of the cell inside heightForRow, just like you do in cellForRow.
You could also have forgotten to set the delegate and datasource properties of the tableview. Or you are returning 0 from numberOfRowsInTable...
That could also be why you are not hitting the breakpoint inside cellForRow.
I'm in the midst of transitioning some of my code from ObjC to Swift. So far so good, but I'm running into an issue with some of my UITableView's delegate methods not being called. In ObjC, I had my cells animate into the view using the tableView willDisplayCell forRowAtIndexPath method. While the method is suggested to me in Swift, it is never called. The same goes for tableView willDisplayHeaderView forSection, and tableView editActionsForRowAtIndexPath.
I'm fairly sure my class is set properly:
class MyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
and my function declarations were suggested, so no way these are incorrect.
func tableView(tableView: UITableView!, editActionsForRowAtIndexPath indexPath: NSIndexPath!) -> [AnyObject]! {
...
}
func tableView(tableView: UITableView!, willDisplayCell cell: UITableViewCell!, forRowAtIndexPath indexPath: NSIndexPath!) {
...
}
etc.
But while the tableView data shows up great, these individual delegate methods never seem to run. Is this a bug, or am I missing something? Thanks!
Did you tell to your table view about delegate and data source?
self.tableView.delegate = self;
self.tableView.datasource = self;