I am using custom cocoa class extends from TableViewCell and it doesn't give any error message but the cells do not appear in the tableview. The scroll gets longer but the table cells are not viewable.
I typed this in my ViewController :
tableView.registerClass(CustomTableViewCell.self, forCellReuseIdentifier: "Cell")
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)->UITableViewCell
{
var cell:CustomTableViewCell? = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as? CustomTableViewCell
if cell == nil {
cell = CustomTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
}
cell!.labTime.text = filtered[indexPath.row].name!
return cell!
}
and my cell class looks like
var labTime = UILabel()
override func awakeFromNib() {
// Initialization code
super.awakeFromNib()
labTime = UILabel(frame: contentView.bounds)
labTime.font = UIFont(name:"HelveticaNeue-Bold", size: 16)
contentView.addSubview(labTime)
}
I don't use any storyBoard or xib file.
Can not find the solution,
thanks
Do this way.
All view intialization of properties should go in init method.
Add this in your custom cell class
var labTime: UILabel!
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
//Do your cell set up
labTime = UILabel(frame: contentView.bounds)
labTime.font = UIFont(name:"HelveticaNeue-Bold", size: 16)
contentView.addSubview(labTime)
}
Add the below line in viewDidLoad method of your view controller.
tableView.registerClass(CustomTableViewCell.self, forCellReuseIdentifier: "Cell")
Set these two delegate - UITableViewDataSource and UITableViewDelegate
Related
A Swift newbie here. I'm trying to learn how to create different UI elements programmatically. I've hit the following wall..
I have 2 .swift files, on one hand we have...
import UIKit
struct MyTableView {
let myCustomTable: UITableView = {
let aTable = UITableView()
aTable.register(MyCustomCell.self, forCellReuseIdentifier: "myCell")
return aTable
}()
}
// custom cell class, then add subviews (UI controls) to it
class MyCustomCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
addSubview(aLabel)
aLabel.frame = CGRect(x:0,
y:0,
width:self.frame.width,
height:self.frame.height)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
// stuff to add to the cell
let aLabel: UILabel = {
let lbl = UILabel()
lbl.text = "My Custom Cell"
lbl.backgroundColor = UIColor.yellow // just to highlight it on the screen
return lbl
}()
On the other hand, we have the following view controller...
import UIKit
class ViewControllerA: UIViewController, UITableViewDelegate, UITableViewDataSource {
private let instanceOfViewControllerTable = MyTableView()
override func loadView() {
super.loadView()
view.frame = UIScreen.main.bounds
instanceOfViewControllerTable.myCustomTable.delegate = self
instanceOfViewControllerTable.myCustomTable.dataSource = self
instanceOfViewControllerTable.myCustomTable.frame = CGRect(x:0,
y:0,
width:self.view.frame.width,
height:self.view.frame.height)
self.view.addSubview(instanceOfViewControllerTable.myCustomTable)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
}
}
It builds and runs successfully, however, I'm getting the following result:
Now, my thinking is if I'm doing something wrong, the cell shouldn't appear at all. What I don't understand, why is it showing only on one cell in the array?
Your help is highly appreciated.
You are declaring aLabel as a global variable. That way, only one instance exists from it. Move it inside your cell's class declaration.
class MyCustomCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
addSubview(aLabel)
aLabel.frame = CGRect(x:0,
y:0,
width:self.frame.width,
height:self.frame.height)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let aLabel: UILabel = {
let lbl = UILabel()
lbl.text = "My Custom Cell"
lbl.backgroundColor = UIColor.yellow // just to highlight it on the screen
return lbl
}()
}
I put my working tableviewcontroller inside a pageviewcontroller. Now I have to register the cell in the tableview programmatically and the method awakeFromNib is not called for the cell. All properties in my custom cell are not initialized and the app crashes if I try to set content.
Is there anything different when I add a tableviewcontroller in a pageviewcontroller?
self.tableView.registerClass(ParticipantCell.self, forCellReuseIdentifier: ParticipantCell.cellIdentifier)
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let index = self.sections[indexPath.section].index+indexPath.row
let participant = self.participants[index]
let cell = tableView.dequeueReusableCellWithIdentifier(ParticipantCell.cellIdentifier, forIndexPath: indexPath) as! ParticipantCell
// cell.setParticipantData(participant)
return cell
}
If you are creating cells programmatically awakeFromNib is not called. However you can do your configurations by overriding:
init(style: UITableViewCellStyle, reuseIdentifier: String?)
As a suggestion you can have a method like this:
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupCell()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupCell()
}
func setupCell() {
// setup your cell here
}
The problem was that the Tableviewcontroller was instantiated wrong. I solved it by instantiating it from the storyboard:
let storyboard = UIStoryboard(name: "Participants", bundle: NSBundle.mainBundle())
if let controller = storyboard.instantiateViewControllerWithIdentifier("ParticipantListController") as? ParticipantListController{
...
}
I have a two custom cells implemented:
class TextFieldCell: UITableViewCell{
var label = UILabel()
var textField = UITextField()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
label.text = "Name"
textField.placeholder = "Enter Task Name Here"
addSubview(label)
addSubview(textField)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
class SwitchCell : UITableViewCell {
var label = UILabel()
var switchControl = UISwitch()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
label.text = "State"
switchControl.on = true
addSubview(label)
addSubview(switchControl)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
In my table view class i have declared this two cells:
let textFieldCell = TextFieldCell(style: .Default, reuseIdentifier: "textFieldCell")
let switchCell = SwitchCell(style: .Default, reuseIdentifier: "switchCell")
and have delegate method in it:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
switch indexPath.row {
case 0: return textFieldCell
case 1: return switchCell
default: return UITableViewCell()
}
}
But when table view loads i've see only switch control on the left of second row. I don't know why.
Try this:
private let reuseIdentifier = "switchCell"
//identifier of your cell.
Seems you have missed registering the cell.
let tableNib = UINib(nibName:"SwitchCell", bundle:nil)
self.tableView!.registerNib(tableNib,forCellReuseIdentifier:reuseIdentifier)
TextFieldCell Added below Code in ViewDidLoad of TableViewCell
self.tableView.registerClass(SwitchCell, forCellReuseIdentifier: "switchCell")
self.tableView.registerClass(TextFieldCell, forCellReuseIdentifier: "textFieldCell")
I am currently learning Swift programatically. I am wanting to add a tableView to a viewController (for the purpose of being able to manipulate the constraints later) and customize the cells with a TableViewCell.
I can do this with my eyes closed when using the storyboard, but when I try to do it with just straight code I have empty cells.
My storyboard is comprised of one (1) empty viewController that has the custom class of ViewController
I have looked at others with similar issues but non of the solutions have worked. Would love to know what I am overlooking (probably something simple). Thanks in advance for the help!
ViewController.swift:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
var tableView: UITableView = UITableView()
var items: [String] = ["Viper", "X", "Games"]
override func viewDidLoad() {
tableView.frame = CGRectMake(0, 0, view.frame.size.width, view.frame.size.height)
tableView.delegate = self
tableView.dataSource = self
tableView.registerClass(TableViewCell.self, forCellReuseIdentifier: "cell")
self.view.addSubview(tableView)
}
func tableView(tableView:UITableView, heightForRowAtIndexPath indexPath:NSIndexPath)->CGFloat
{
return 50
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.items.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableViewCell
//cell.textLabel?.text = self.items[indexPath.row]
cell.companyName.text = "name"
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
TableViewCell:
import UIKit
class TableViewCell: UITableViewCell {
var companyName = UILabel()
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
companyName.frame = CGRectMake(0, 0, 200, 20)
companyName.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(companyName)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Hello #Michael First thing is you should only use awakeFromNib when you are using a .xib(Nib) and in your case you are using custom class without such xib so, you should use
override init(style: UITableViewCellStyle, reuseIdentifier: String?){
super.init(style: style, reuseIdentifier: reuseIdentifier)
companyName = UILabel(frame: CGRectMake(0, 0, 200, 20))
contentView.addSubview(companyName)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
also you should initialise your label before using it.
this will solve your problem.
Read apple's documentation for subclassing UITableViewCell here.
If you want your custom cell to load from some custom xib you do sometimes like:
tableView.registerNib(UINib(nibName: "CustomTableViewCell", bundle: NSBundle.mainBundle()), forCellReuseIdentifier: "CustomTableViewCell")
And you should have CustomTableViewCell.xib file where you have table view cell with reuse identifier CustomTableViewCell
Checkout how your cell's companyLabel is laid out. Does it exist or no?
In your code, I replaced companyLabel with default textLabel and it worked for me.
cell.textLabel!.text = self.items[indexPath.row]
I think awakeFromNib is not called because you do not register a nib but a class. Try this instead:
class TableViewCell: UITableViewCell {
let companyName = UILabel()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// Initialization code
companyName.frame = CGRectMake(0, 0, 200, 20)
companyName.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(companyName)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
I am using the below custom UITableViewCell without nib file.
I have no problem in viewing it in my UITableViewController.
My problem is with assigning a text to "name" label cell.name.text = "a Name" .. noting is assigned
Can you help me?
import UIKit
class ACMenuCell: UITableViewCell {
#IBOutlet var name : UILabel!
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
name = UILabel(frame: CGRectMake(20, 10, self.bounds.size.width , 25))
name.backgroundColor = .whiteColor()
self.contentView.addSubview(name)
self.contentView.backgroundColor = .blueColor()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func layoutSubviews() {
super.layoutSubviews()
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
You might want to try this: Create a public function in a subclass of UITableViewCell, and inside this funxtion set the text to label.
(void)initializeCell
{
do whatever like setting the text for label which is a subview of tableViewCell
}
And from cellForRowAtIndexPAth, call this function on cell object:
// taking your code for demo
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let reuseIdentifierAC:NSString = "ACMenuCell"; var cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifierAC, forIndexPath:indexPath) as ACMenuCell cell = ACMenuCell(style: UITableViewCellStyle.Default, reuseIdentifier: reuseIdentifierAC) [cell initializeCell] return cell }
This approach has worked for me.