New or Existing cell when using dequeueReusableCellWithIdentifier:forIndexPath:? - ios

Having a UITableViewControllerand using:
override func tableView(tableView: UITableView, cellForRowAtIndexPath
indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as! UITableViewCell
return cell
}
Using dequeueReusableCellWithIdentifier:forIndexPath:'' instead ofdequeueReusableCellWithIdentifier`` how can I determine if a cell is a new one or a reused one?

Create your own custom cell class to use for the reuse identifier. Then, inside that cell, implement awakeFromNib and make your changes to the cell. This will only be called once when your cell is loaded from its NIB file.
Any other changes that need to be made when the cell is reused can be made in prepareForReuse.

Related

Adding views programmatically into tableView cells making scroll jerky and slow

Adding views programmatically into tableView cells making scroll jerky and slow. I am adding views programmatically into cell in the delegate function "CellForRowAt". I tried it through delegate function "WillDisplay" but the results are the same.
What is the best possible solution to achieve this?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:
"cell", for: indexPath) as! CustomCell
addViewsInCell(cell: cell, indexPath: indexPath)
return cell
}
func addViewsInCell(cell: CustomCell, indexPath: IndexPath) {
//here i am adding some views programmatically
for i in 0..<3 {
let customView: CustomView = Bundle.main.loadNibNamed("CustomView", owner: self, options: nil)![0] as! customView
cell.customViewPlacement.addSubview(customView)
}
}
Cell views are reused. Adding a subview every time in cellForRowAt indexPath: you end up with multiple copies of the same subview. Instead you should check whether that subview is already added. You could mark your subview with a tag and then use the viewWithTag method to test its presence.
Don't add any subviews/custom views inside tableView: cellForRowAt indexPath:. This will cause those subviews to be added repeatedly whenever that cell loaded by the table view. Instead create a subclass of UITableViewCell and create your subviews inside that subclass if you are working programmatically. Or else if you are working with storyboards, you can create a dynamic prototype cell.

Two TableViews that have same prototype cell, constraints behave differently

I created two ViewControllers and two TableViews. Then i added prototype cell to one TableView, set it up according to my needs, copied it to the other TableView, changed its class and identifier and linked it up in ViewController that is datasource and delegate for each one.
The problem is, FEEDING one is behaving good, having constraints as expected, and the WALKING one is not, but i have no idea why since they have all same properties in each one's:
ViewControllers:
FEEDING
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = myFeedingTableView.dequeueReusableCellWithIdentifier("feedingcell", forIndexPath: indexPath) as! FeedingCell
cell.time.text = self.vremena[indexPath.row]
return cell
}
WALKING
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = myWalkingTableView.dequeueReusableCellWithIdentifier("walkingcell", forIndexPath: indexPath) as! WalkingCell
cell.time.text = self.vremena[indexPath.row]
return cell
}
CustomCell files
each one is connected to its class
FeedingCell is class of feeding prototype cell
WalkingCell is class of feeding prototype cell
Constraints
and the constraints are same, as you can see on the picture.
Here is the image providing different results and constraints:
image
Solved by changing rowHeight settings in TableView. Thanks #SilentLupin

Swift : UITableViewCell Overlapping in debug view Hierarchy

Cells Overlapping
I used custom class for UITableViewCell. It look fine
but the debug view Hierarchy cells is overlapping as image above.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(self.reuseIdentify, forIndexPath: indexPath) as! ContactViewCell
cell.lbContactName.text = self.dataSource[indexPath.row]
return cell
}
Please check the custom UITableviewCell Clip Subviews property.

UITableView with transparent cells overlap old cells when reloading data

I have a UITableView with a transparent background color and cells which also have a transparent background color. When I reload my tableView with:
dataSource = some new data
tableView.reloadData()
I can see the new cells overlap the old ones.
I did try to use use
tableView.beginUpdates()
// remove all rows here
change data source
// insert new rows here
tableView.endUpdates()
but it did not work. I tried as well tableView.reloadRowsAtIndexPath(...) but still no luck.
And finally I set all my cells and my table view to clear graphic context when redrawn but it did not manage to fix this issue.
Any help would be greatly appreciated.
My cell creation function:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("suggestioncell")
cell.backgroundColor = UIColor.whiteColor().alpha(0.1)
cell.textLabel?.text = (suggestions![indexPath.row] as! SVPlacemark).formattedAddress
cell.clearsContextBeforeDrawing = true
cell.contentView.clearsContextBeforeDrawing = true
return cell
}
Try overriding prepareForReuse in you UITableViewCell subclass, and reset content there.
Here's what the documentation says about that:
Prepares a reusable cell for reuse by the table view's delegate.
If a UITableViewCell object is reusable—that is, it has a reuse identifier—this method is invoked just before the object is returned from the UITableView method dequeueReusableCellWithIdentifier:. For performance reasons, you should only reset attributes of the cell that are not related to content, for example, alpha, editing, and selection state. The table view's delegate in tableView:cellForRowAtIndexPath: should always reset all content when reusing a cell. If the cell object does not have an associated reuse identifier, this method is not called. If you override this method, you must be sure to invoke the superclass implementation.
Custom UITableViewCell class:
class customCell: UITableViewCell {
override func prepareForReuse() {
self.textLabel?.text = nil
}
}
In your cellForRowAtIndexPath method:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("suggestionCell", forIndexPath: indexPath) as! customCell
cell.backgroundColor = UIColor.whiteColor().alpha(0.1)
cell.textLabel?.text = (suggestions![indexPath.row] as! SVPlacemark).formattedAddress
return cell
}
And, of course in your XIB/Storyboard, set the cell class to CustomCell, and set its reuse identifier.

Subclassing UITableViewCell on Swift - Error edit UITableView rows

Using Swift: I've hooked up an NSFetchedResultsController to a UITableView, and created a subclass of UITableViewCells for the TableView cells.
The UITableViewCells format and display correctly. But the app crashes as soon as I try editing the rows (adding or deleting).
For testing, I've used the most basic subclass possible: An empty subclass, and it still crashes. The original UITableViewCell works normally.
Any ideas? Swift bug? The crash goes straight to the top of the stack. I get nothing in the console.
Works:
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell? {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let task = fetchedResultController.objectAtIndexPath(indexPath) as Tasks
cell.textLabel.text = task.desc
return cell
}
Doesn't work:
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell? {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell2
let task = fetchedResultController.objectAtIndexPath(indexPath) as Tasks
cell.textLabel.text = task.desc
return cell
}
When subclass is:
import UIKit
class UITableViewCell2: UITableViewCell {
}
If you create table cells programmatically (not in InterfaceBuilder) you have to register the table cell class with
TableView.registerClass(..., forCellReuseIdentifier...)

Resources