Reputation: 54706
I've been stuck with this problem for days, so I'd be really happy if someone could help. I'm trying to create a dynamic UITableView, for which I created a custom UITableView subclass and I've created a custom UITableViewCell subclass as well, because I need several UILabels and a UIButton in each cell. The cell is created, but the problem is that the value of the labels is always nil, hence the cell isn't displayed properly. This is, how the storyboard looks like, and this is what I see while running the program.
Here's my UITableViewCell subclass:
import UIKit
class QuestionTableViewCell: UITableViewCell {
@IBOutlet var student: UILabel!
@IBOutlet var labDesk: UILabel!
@IBOutlet var topic: UILabel!
@IBOutlet var answers: UILabel!
}
and my UITableView subclass:
import UIKit
class QuestionViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet var table: UITableView!
struct Question {
var student: String
var labDesk: String
var topic: String
var answered: String
}
override func viewDidLoad() {
super.viewDidLoad()
table.estimatedRowHeight = 50
table.dataSource = self
table.delegate = self
self.table.registerClass(QuestionTableViewCell.self, forCellReuseIdentifier: "cell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as QuestionTableViewCell
cell.student.text = "random string"
cell.labDesk?.text = "25/A"
cell.topic?.text = "string"
cell.answers?.text = "3"
return cell
}
}
Upvotes: 29
Views: 21714
Reputation: 2388
Issue I was facing: TableViewCell has been created and all the IBOutlets are nil. So I can't set any values such as text or color etc. Below code worked for me.
Xcode version: 13.3
Step 1: Remove datasource and delegate reference form storyboard.
Step 2: In viewDidLoad add,
tableView.delegate = self
tableView.dataSource = self
Step 3: In tableview UITableViewDataSource cellForRowAt function, add your cell the given way.
let cell = tableView.dequeueCell(ofType: YourCellName.self)
cell.yourCellFunction()
return cell
Note 1: dequeueCell(ofType...) is calling the below function internally. you don't need to use it directly.
func dequeueCell<T: UITableViewCell>(ofType type: T.Type) -> T {
}
Important: You don't need to provide any "Resporation ID" or "Reuse Identifier" for cell. It works with your cell name.
Upvotes: -1
Reputation: 8131
Make sure that the selected cell is in the right "module
" and if necessary, inherit:
If not, your IBOutlets
will be nil.
Upvotes: 0
Reputation: 5876
Don't forget to add:
tableView?.register(UINib(nibName: "xyz",
bundle: nil),
forCellReuseIdentifier: "abc")
Upvotes: 1
Reputation: 1
If you haven't added constraints for the label then they will not be created though the custom cell is created. Make sure you added some constraints.
Upvotes: 0
Reputation: 1311
The most important part is to register the xib containing the custom cell with the table view. Therefore add the following code in viewDidLoad() method.
let nib = UINib.init(nibName: "MyCustomCell", bundle: nil)
self.tblUsers.register(nib, forCellReuseIdentifier: "MyCustomCell")
Upvotes: 8
Reputation: 6500
If you are using a table cell with Xib. you need to register your cell with ..
register(_:forCellReuseIdentifier:)
Upvotes: 0
Reputation: 141
For those who are still trying to figure this out after trying all those possible solutions:
Disconnect/Reconnect the IBOutlets in your Storyboards should do the trick!
Upvotes: 2
Reputation: 291
If you're using a cell with a nib then make sure that you are registering the cell with the table view using registerNib:forCellReuseIdentifier:
. If the cell just has a class then use registerClass:forCellReuseIdentifier:
.
Upvotes: 29
Reputation: 901
Try removing self.table.registerClass(QuestionTableViewCell.self, forCellReuseIdentifier: "cell")
Upvotes: 74
Reputation: 10752
I might be late here, but I just solved a similar problem.
Make sure you've set the Identifier in InterfaceBuilder on your UITableViewCell.
Upvotes: 3
Reputation: 12758
First, you don't have to register the class if it exists in Interface Builder.
Second, you should dequeueReusableCellWithIdentifier:forIndexPath
instead of dequeueReusableCellWithIdentifier
.
Third, UITableViewController
already has a property called tableView
so there is no need to make an IBOutlet to table
as UITableViewController already handles this. It also conforms to the UITableViewDataSource
and UITableViewDataSource
so these are extraneous.
Fourth, don't set the properties for table
set them for tableView
.
Fifth, cell.labDesk.text = ""
is sufficient, no need to make it optional.
If all your IBOutlets are hooked up, Cell Identifiers correctly set, and these revisions are made, it will work.
class QuestionTableViewCell: UITableViewCell {
@IBOutlet var student: UILabel!
@IBOutlet var labDesk: UILabel!
@IBOutlet var topic: UILabel!
@IBOutlet var answers: UILabel!
}
class QuestionViewController: UITableViewController {
struct Question {
var student: String
var labDesk: String
var topic: String
var answered: String
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = 50
tableView.dataSource = self
tableView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as QuestionTableViewCell
cell.student.text = "random string"
cell.labDesk.text = "25/A"
cell.topic.text = "string"
cell.answers.text = "3"
return cell
}
}
Upvotes: 8