I'm having an issue where my app will freeze if when I press it to got the next scene which is a view controller with a tableview nested inside of it. the app will only freeze when I've declared how many rows the table will have. If anyone knows how to fix this problem its be greatly appreciated.
class ViewController: UIViewController, UITableViewDataSource {
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell()
cell.textLabel?.text = "hello"
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Have you set dataSource of your table view? You must call tableView.dataSource = self somewhere in your code (most probably in viewDidLoad method)
The problem with your code is that in tableView(_:cellForRowAtIndexPath:) you are creating new cell every time the method is called. That is not how table views (or collection views) work.
The idea behind these components is to reuse their cells so that your application shows better performance. What if you have 1000 cells? You will create 1000 UITableViewCell objects for each cell? This is where dequeueReusableCellWithIdentifier(_:) comes in handy.
So set an identifier for your cell in Interface Builder, for example "Cell" and get the cell like this:
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
This is the right way to go.
You have to make sure you set the correct reuse identifier for your table view cell (either in storyboard, or code).
Storyboard:
Of if you want to do it in code, put this in viewDidLoad():
tableView.registerClass(UITableViewCell, forHeaderFooterViewReuseIdentifier: "cellIdentifier")
Important to know that you should only use one of the above. If you define your UI in Storyboards, I recommend the first approach.
Then when you create the cell in tableView(_:, cellForRowAtIndexPath), instead of this:
var cell = UITableViewCell()
Use a cell from the reuse queue like so:
var cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier", forIndexPath: indexPath) as! UITableViewCell
Everytime you are creating object for cell, make sure you use reuse identifier.
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
Related
I have a UITableViewController and want to populate it with custom cells. The cell I have created has it's own class and xib file, away from the main storyboard.
In the xib file, I have 'VisitCell' as the identifier.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "VisitCell", for: indexPath) as! VisitCell
let visit : BookingVisitItem = bookingDayItem.getVisitItems()[indexPath.row]
cell.locationLabel?.text = visit.getVenueName()
cell.timeLabel?.text = visit.getVisitTime()
cell.typeLabel?.text = visit.getVisitType()
return cell
}
If I run the code like this, it seems to crash. Maybe it can't find the custom cell?
However, if I add the following to viewDidLoad()
tableView.register(VisitCell.self, forCellReuseIdentifier: "VisitCell")
At this stage, it doesn't crash but the table view appears to be empty.
Any pointers? Thanks!
Register your nib cell in viewDidLoad()-:
override func viewDidLoad() {
super.viewDidLoad()
yourTableView.registerNib(UINib(nibName: "yourcell", bundle: nil), forCellReuseIdentifier: "CustomCellOne")
}
According to my other thread, I have a signal SIGABRT error in my code. The code consists of:
A Storyboard with 1 TableView and 1 Table Cell included
A custom Tablecell class (TableViewCell_Prototyp), which is connected to the Storyboard by (strong) IBoutlets.
A View Controller class, which is described in the following.
My ViewController class is connected to 3 super-classes: UIViewController, UITableViewDelegate, UITableViewDataSource. In addition, there are 3 functions implemented. Can somebody find the mistake ?
override func viewDidLoad() {
super.viewDidLoad()
}
i don't know what happens here. It was written by default so it should not cause any errors.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
i just want one table cell to be returned.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell (withIdentifier: "picCell") as! TableViewCell_Prototyp
cell.shoutPic.image = #imageLiteral(resourceName: "Bildschirmfoto 2017-06-05 um 10.11.21")
cell.shoutText.text = "Hallooooooooo"
return cell
}
shoutPic and shoutText is connected to the TableViewCell_Prototype custom class by outlets.
When you have custom table cell classes registered for your tableView, it's better to dequeue them using dequeueReusableCell(withIdentifier:for:), like so:
let cell = tableView.dequeueReusableCell(withIdentifier: "picCell", for: indexPath) as! TableViewCell_Prototyp
If this is all of your code, I would check that your prototype cell's identifier matches "picCell" exactly and that its class is set to TableViewCell_Prototyp
I think #Gereon is right that you need to dequeue with a different method.
Having the class TableViewCell_Prototyp is not enough -- you need to set it to the cell in the Storyboard file. Click on the cell in the storyboard and set it in the Identity tab.
I need to add cell identifier to make ReusableCell for tableView. However I don't see any cell in the tableView properties and table view hierarchical. how to add a cell in the table view .
note : basically i want to create a Xib file which should contain a tableView and that tableView should have custom UiTableViewCell
code here :
class SuggestNearTableViewCollectionViewCell: UICollectionViewCell , UITableViewDataSource,UITableViewDelegate{
#IBOutlet weak var suggestTableView : UITableView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.suggestTableView.dataSource = self
self.suggestTableView.delegate = self
suggestTableView.register(UINib(nibName: "SuggestNearTableViewCell", bundle: nil), forCellReuseIdentifier: "SuggestNearTableViewCell")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SuggestNearTableViewCell", for: indexPath) as! SuggestNearTableViewCell
return cell
}
}
First of all go to File-> new -> Cocoa Touch Class and create class of UIViewCOntroller. Name your class accordingly.
Now you will have a Xib file and a Swift file. Xib would look something like this.
Now drag and drop a UITableView on the Xib and give it 4-pin constraints as top=0, bottom=0, leadin=0, and trailing=0. Now create an outlet of your tableView in your newly created swift file. Connect data Source and delegate as well.
Now again go to File->New-> Coucoa Touch Class and create a class for UItableViewCell also create a Xib file like below.
Now you will have a Xib for your cell and a swift file for your cell. Just design your cell as your need in this Xib. Lets say If you want to put an imageView or a label etc. Then create outlets of all components in swift file of your custom cell. Now add this function in swift file of your custom cell.
class func cellForTableView(tableView: UITableView, atIndexPath indexPath: NSIndexPath) -> YourCustomTableViewCell {
let kYourCustomTableViewCellIdentifier = "kYourCustomTableViewCellIdentifier"
tableView.registerNib(UINib(nibName: "YourCustomTableViewCell", bundle: NSBundle.mainBundle()), forCellReuseIdentifier: kYourCustomTableViewCellIdentifier)
let cell = tableView.dequeueReusableCellWithIdentifier(kYourCustomTableViewCellIdentifier, forIndexPath: indexPath) as! YourCustomTableViewCell
return cell
}
Your custom cell is ready to use.
Now go to the swift file of your tableView and in your cellForRowAtIndexPath just use use this cell like below.
let cell = YourCustomTableViewCell.cellForTableView(tableView, atIndexPath: indexPath)
cell.myImageView.image = "something"
// Do something with your cell
I hope it would be helpfull. Let me know if you find any difficulty.
Inside tableViewController in viewDidLoad you should register it like this:
tableView.registerNib(UINib(nibName: "CustomOneCell", bundle: nil), forCellReuseIdentifier: "CustomCellOne")
And inside cellForRowAtIndexPath just declare cell:
let cell: CustomOneCell = tableView.dequeueReusableCellWithIdentifier("CustomCellOne", forIndexPath: indexPath) as! CustomOneCell
If you are not doing it inside tableViewController then you gotta connect your tableView and delegate:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
...
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Table view delegate
self.tableView.delegate = self
self.tableView.dataSource = self
...
I would like to confirm the approach I took to solve an issue with dequeuing custom cells in a UITableView as it scrolls such that the cells do not contain the old cell's data...
The app that contains a UITableView with custom UITableViewCells ("CustomCell"). Each CustomCell contains a UIStackView with one or more custom views via a nib ("CustomView"). I reuse the CustomCell as follows:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(ReuseIdentifierCustomCell, forIndexPath: indexPath) as! CustomCell
configureCell(cell, atIndexPath: indexPath)
return cell
}
The issue was that the cell would contain "old" data as the cell was being reused. To fix this, I override the prepareForReuse method in CustomCell as follows:
override func prepareForReuse() {
super.prepareForReuse()
for case let view as CustomView in stackView.subviews {
view.removeFromSuperview()
}
}
Then in layoutSubviews, I add the subviews back in:
override func layoutSubviews() {
super.layoutSubviews()
if stackView.subviews.isEmpty {
addCustomViewsToCell()
}
}
Performance seems fine thus far, but curious if this is a proper approach or if I will run into issues with scale in the future. I have not been able to find another workable approach thus far.
Thanks
Your code to reuse cells is correct. A common approach is to configure your cell's data within the cellForRowAtIndexPath function by setting a variable or calling a function on your custom cell:
let cell = tableView.dequeueReusableCellWithIdentifier(ReuseIdentifierCustomCell, forIndexPath: indexPath) as! CustomCell
cell.data = myData[indexPath.row] // where myData is an array of type [Data]
return cell
Your cell would be in charge of its own layout to display the new data:
var data: Data {
didSet {
// configure and refresh your UI here
}
}
I suspect your issue has to do with your configureCell function. If you can, move this code into your cell's logic instead. This will be cleaner and easier to understand.
As far as performance, you might be fine now if your stack views don't have much content in them, but if they continue to grow in complexity you might see frame rate drops on older devices.
This is my first time using TableView's and I've already hit a road block.
I've got a View Controller with a Container inside. The Container View has an embedded Table View Controller. I have populated the table view controller using the below code. I have set the datasource and the delegate to the Table View Controller, set the Custom Class of the Table View controller to ORMTableVC and set the Table View cell Identifier to cellIdentifier.
My problem is at runtime the View Controller is just blank and I cannot see any Table lines or data.
Any help will be greatly appreciated.
import Foundation
import UIKit
class ORMTableVC : UITableViewController {
let cellIdentifier = "cellIdentifier"
var Array = [String]()
override func viewDidLoad() {
super.viewDidLoad()
Array = ["Reps", "Weight", "RPE", "Fatigue", "Potential Max", "Fatigue Weight"]
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Array.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let Cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath)
Cell.textLabel?.text = Array[indexPath.row]
return Cell
}
}
StoryBoard Setup
Built App
After looking through many tutorials managed to fix this. Seemed like the code wasn't the issue it was the storyboard setup.
On the Table View Cell the identifier needed to be cellIdentifier not Cell.