creating custom tableview cells in swift
Solution 1
Thanks for all the different suggestions, but I finally figured it out. The custom class was set up correctly. All I needed to do, was in the storyboard where I choose the custom class: remove it, and select it again. It doesn't make much sense, but that ended up working for me.
Solution 2
Custom Table View Cell Example
Tested with Xcode 9 (edit also tested on 11 / 12 Beta 2) and Swift 4 (edit: also tested on 5.2)
The asker of the original question has solved their problem. I am adding this answer as a mini self contained example project for others who are trying to do the same thing.
The finished project should look like this:
Create a new project
It can be just a Single View Application.
Add the code
Add a new Swift file to your project. Name it MyCustomCell.swift. This class will hold the outlets for the views that you add to your cell in the storyboard.
import UIKit
class MyCustomCell: UITableViewCell {
@IBOutlet weak var myView: UIView!
@IBOutlet weak var myCellLabel: UILabel!
}
We will connect these outlets later.
Open ViewController.swift and make sure you have the following content:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
// These strings will be the data for the table view cells
let animals: [String] = ["Horse", "Cow", "Camel", "Sheep", "Goat"]
// These are the colors of the square views in our table view cells.
// In a real project you might use UIImages.
let colors = [UIColor.blue, UIColor.yellow, UIColor.magenta, UIColor.red, UIColor.brown]
// Don't forget to enter this in IB also
let cellReuseIdentifier = "cell"
@IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
// number of rows in table view
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.animals.count
}
// create a cell for each table view row
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:MyCustomCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! MyCustomCell
cell.myView.backgroundColor = self.colors[indexPath.row]
cell.myCellLabel.text = self.animals[indexPath.row]
return cell
}
// method to run when table view cell is tapped
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You tapped cell number \(indexPath.row).")
}
}
Setup the storyboard
Add a Table View to your view controller and use auto layout to pin it to the four sides of the View Controller. Then drag a Table View Cell onto the Table View. And then drag a View and a Label onto the Prototype cell. (You may need to select the Table View Cell and manually set the Row Height to something taller in the Size inspector so that you have more room to work with.) Use auto layout to fix the View and the Label how you want them arranged within the content view of the Table View Cell. For example, I made my View be 100x100.
Other IB settings
Custom class name and Identifier
Select the Table View Cell and set the custom class to be MyCustomCell
(the name of the class in the Swift file we added). Also set the Identifier to be cell
(the same string that we used for the cellReuseIdentifier
in the code above.
Hook Up the Outlets
- Control drag from the Table View in the storyboard to the
tableView
variable in theViewController
code. - Do the same for the View and the Label in your Prototype cell to the
myView
andmyCellLabel
variables in theMyCustomCell
class.
Finished
That's it. You should be able to run your project now.
Notes
- The colored views that I used here could be replaced with anything. An obvious example would be a
UIImageView
. - If you are just trying to get a TableView to work, see this even more basic example.
- If you need a Table View with variable cell heights, see this example.
Solution 3
This is for who are working custom cell with .xib
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let identifier = "Custom"
var cell: CustomCell! = tableView.dequeueReusableCellWithIdentifier(identifier) as? CustomCel
if cell == nil {
tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: identifier)
cell =tableView.dequeueReusableCellWithIdentifier(identifier) as? CustomCell
}return cell}
Solution 4
I have the same problem.
Generally what I did is the same as you.
class dynamicCell: UITableViewCell {
@IBOutlet var testLabel : UILabel
init(style: UITableViewCellStyle, reuseIdentifier: String) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
and in the uitableviewcell method:
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell :dynamicCell = tableView.dequeueReusableCellWithIdentifier("cell") as dynamicCell
cell.testLabel.text = "so sad"
println(cell.testLabel)
return cell;
}
and yeah the tableview shows nothing! But guess what, it actually shows something...because the log I get from the println(cell.testLabel) shows that all the Labels are actually displayed out.
BUT! their Frames is strange, which have something like this:
frame = (0 -21; 42 21);
so it has a (0,-21) as (x,y), so that means the label just appears at somewhere outside the bound of the cell.
so I try to add adjust the frame manually like this:
cell.testLabel.frame = CGRectMake(10, 10, 42, 21)
and sadly, it doesn't work.
---------------update after 10 min -----------------
I DID IT. so, it seems that the problem comes from the Size Classes.
Click on your .storyboard file and go to the File Inspector Tab
UNCHECK THE Size Classes checkbox
and finally, my "so sad"Label comes out!
Solution 5
Last Updated Version is with xCode 6.1
class StampInfoTableViewCell: UITableViewCell{
@IBOutlet weak var stampDate: UILabel!
@IBOutlet weak var numberText: UILabel!
override init?(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init(coder aDecoder: NSCoder) {
//fatalError("init(coder:) has not been implemented")
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
Nilzone-
The worst thing about programming is that it does exactly what you tell it to do - not what you want it to do.
Updated on June 23, 2021Comments
-
Nilzone- about 3 years
I have a custom cell class with a couple of IBOutlets. I have added the class to the storyboard. I have connected all my outlets. my cellForRowAtIndexPath function looks like this:
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as SwipeableCell cell.mainTextLabel.text = self.venueService.mainCategoriesArray()[indexPath.row] return cell }
Here is my custom cell class:
class SwipeableCell: UITableViewCell { @IBOutlet var option1: UIButton @IBOutlet var option2: UIButton @IBOutlet var topLayerView : UIView @IBOutlet var mainTextLabel : UILabel @IBOutlet var categoryIcon : UIImageView init(style: UITableViewCellStyle, reuseIdentifier: String!) { super.init(style: style, reuseIdentifier: reuseIdentifier) } }
When I run the app, all my cell are empty. I have logged out
self.venueService.mainCategoriesArray()
and it contains all the correct strings. I have also tried putting an actual string equal to the label, and that produces the same result.What am I missing? Any help is appreciated.
-
Paul Brewczynski almost 10 yearsWhat the heck is this "size classes" things ? And why does it resolve problem ? I hade exactly the same problem, even the origin of the custom label was the same (0 -21). But what's interesting, after unchecking "use size classes" it worked, and when i CHECK IT AGAIN it also worked... So it looks like a bug.
-
S.H. almost 10 yearssize classes seems to me that lets the Xcode resize the Views and ViewControllers to different devices without doing too much additional work. Once you remove it the data of those other devices get deleted. So Re-checking it again doesn't automagically creates it hence it will still work. I had the same problem.
-
Joris Weimar over 8 yearsWhen you select a custom class, it also needs a module. If you enter the custom class name before you have actually created the class, the module isn't set. That's happened to me before, maybe that's what happened to you, too.
-
Suragch about 8 years@codebased, I haven't actually tried that myself yet, but I would start by adding gesture recognizers to the separate views.
-
rockhammer about 8 years@Suragch thank you for the detailed explanation. In following your steps, I'm getting this error in the console "fatal error: unexpectedly found nil while unwrapping an Optional value" and errmsg "EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP, subcode=0x0) at compile time at the let cell:MyCustomCell = self.tableView.... line. Might you know what I am missing? Thanks a lot. The only change I've made is to use 2 UILabels instead of an image and a label.
-
Suragch about 8 years@rockhammer, two possibilities are that you (1) didn't connect the
IBOutlet
or (2) wrote thecellReuseIdentifier
string name wrong in IB. If it is neither of these, check the other answers on SO that describe your problem. There are many of them. Example. -
MobileMon over 7 yearsThe cell xib should be registered somewhere else like in viewDidLoad so it doesn't get called multiple times
-
mfaani over 7 yearshow can you set the
tableViewCell
's style? Can't I customize a UITableViewCell that has a rightDetail style? I want to do it all programatically, but I just don't know how to setup the cell with that style -
Suragch over 7 years@Honey, I haven't done that either. If this doesn't address your question it might be a good candidate for a new one.
-
mfaani over 7 yearsThanks. read that before, it's objective-c and its being done from tableView, as far as I know, you don't initiate a tableviewCell, you just register and dequeue it. Please correct me if I'm wrong.
-
Suragch over 7 years@Honey, If you want to formulate this as a new question I'm willing to look at it. I don't really understand what it is that isn't working for you currently.
-
J A S K I E R over 5 yearsI had a similar problem. Helped to rename @IBOutlet weak var image: UIImageView! Because "image" - system name.
-
CristianMoisei over 5 yearsHey @Suragch I followed this to set up my custom cell and it worked great, thank you. I can't seem to be able to use outlets to change properties of views inside my custom cell. Am I missing something? Would you be able to have a look? stackoverflow.com/questions/55315771/…