I've created UITableView and UITableViewCell programmatically. In my ViewController - viewDidLoad I do:
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.registerClass(newsCell.self, forCellReuseIdentifier: "newsCell")
later use it as:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("newsCell", forIndexPath: indexPath) as! newsCell
return cell
}
My newsCell class(shortly):
class newsCell: UITableViewCell {
let scoreLabel = UILabel()
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
print("init")
self.addSubview(self.scoreLabel)
}
}
but I do not even get init on logs, so it does not call my custom cell at all. What is a problem?
Try this code below:
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: restorationIdentifier)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
and forced unwrapping is dangerous. You should do it like this:
if let cell = self.tableView.dequeueReusableCellWithIdentifier("newsCell", forIndexPath: indexPath) as? newsCell{}
Related
In iOS 14 TableView with textField is not working. Is someone have solution ?
Here is sample code:
class TestController: UIViewController {
let tableView: UITableView = {
let tableView = UITableView(frame: .zero, style: .grouped)
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
view.addSubview(tableView)
tableView.edgesToSuperview()
tableView.backgroundColor = .gray
tableView.register(TestCell.self, forCellReuseIdentifier: TestCell.reuseID)
tableView.dataSource = self
}
}
extension TestController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: TestCell.reuseID, for: indexPath)
return cell
}
}
class TestCell: UITableViewCell {
let textField = UITextField()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
backgroundColor = .red
addSubview(textField)
textField.height(50)
textField.backgroundColor = .blue
textField.edgesToSuperview()
selectionStyle = .none
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
The same code works on iOS 13 but is not working on iOS 14. Is someone fixed this issue ? (Xcode Version 12.0 (12A7209))
You should not use directly addSubview in a cell but instead add it inside the ContentView:
contentView.addSubview(textField)
This should work and solve your problem
In iOS 14 the UITableViewCellContentView hierarchy is different.
In tableView(_:cellForRowAt:), instead of doing something like this:
cell.addSubview(textField)
Change it to:
cell.contentView.addSubview(textField)
I am making a view controller with tableView for presenting individual news cards. I want to load cells once and for all (without reusing it as usual). So I do this:
tableView.register(UINib(nibName: "RatingNewsCell", bundle: nil), forCellReuseIdentifier: "RatingNewsCell")
tableView.register(UINib(nibName: "PromoNewsCell", bundle: nil), forCellReuseIdentifier: "PromoNewsCell")
var cells = [UITableViewCell]()
let rating = RatingNewsCell()
rating.delegate = self
cells.append(rating)
etc...
self.items = cells
Cells are loaded like this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
return items[indexPath.section]
}
Cell code looks like this:
class RatingNewsCell: UITableViewCell
{
var delegate: RatingNewsCellDelegate?
#IBOutlet weak var shopNameLabel: UILabel!
#IBOutlet weak var bouquetImageView: RoundImageView!
#IBOutlet weak var floristImageView: RoundImageView!
#IBOutlet weak var ratingControl: RatingPicker!
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
{
super.init(style: style, reuseIdentifier: "RatingNewsCell")
}
required init?(coder decoder: NSCoder)
{
super.init(coder: decoder)
}
override func awakeFromNib()
{
super.awakeFromNib()
ratingControl.setSelected(newIndex: 0)
}
}
In the result I've got a table view, but cell just appears blank:
Any ideas?
I suggest to refactor your code to use tableView's datasource method though you are only using static cells.
enum Section: Int {
case RatingNews
case PromoNews
static var count: Int { return Section.PromoNews.rawValue + 1 }
}
func numberOfSections(in tableView: UITableView) -> Int {
return Section.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let section = Section(rawValue: indexPath.section)!
switch section {
case .PromoNews:
let cell = tableView.dequeueReusableCell(withIdentifier: "RatingNewsCell", for: indexPath) as! RatingNewsCell
return cell
case .RatingNews:
let cell = tableView.dequeueReusableCell(withIdentifier: "PromoNewsCell", for: indexPath) as! PromoNewsCell
return cell
}
}
You need to call
tableView.delegate = self
and
tableView.dataSource = self
Alright, I am trying to add content to my custom tableview cell programmatically as demonstrated in mob last question here - Swift: tableview cell content is added again and again with each reload? initializing all the content in func tableView() results in overlapping.
I have followed this question verbatim Swift. Proper initialization of UITableViewCell hierarchy And in my custom cell class (which I give a name to in my storyboard) I have:
class EventTableCellTableViewCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier) // the common code is executed in this super call
// code unique to CellOne goes here
print("INIT")
self.contentView.backgroundColor = UIColor.blackColor()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
And this init is not called because nothing is printed. The errors come in my func tableView() in my main VC. I originally had:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("eventCell", forIndexPath: indexPath) as! EventTableCellTableViewCell
// cell.eventTitle.text = names[indexPath.row]
// cell.eventDescription.text = descriptions[indexPath.row]
cell.contentView.clipsToBounds = false
//cell UIX
let eventTitleLabel = UILabel()
let dateLabel = UILabel()
let authorLabel = UILabel()
let locationLabel = UILabel()
let categoryView = UIImageView()
//then I add everything
But this didn't work so I looked at other posts and now have:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//var cell = tableView.dequeueReusableCellWithIdentifier("eventCell", forIndexPath: indexPath) as! EventTableCellTableViewCell
var cell = tableView.dequeueReusableCellWithIdentifier("eventCell", forIndexPath: indexPath) as! UITableViewCell
if (cell == nil) {
cell = EventTableCellTableViewCell.init(style: .Default, reuseIdentifier: "eventCell")
}
I have also tried doing it without the indexPath. Right now I get an error that cell cannot == nil, and not matter what I write init is not called.
How can I configure my cell programmatically?
If the cell is designed in the storyboard only init?(coder aDecoder: NSCoder) is called, init(style: style, reuseIdentifier: is never called.
And you have to set the class of the cell in Interface Builder to EventTableCellTableViewCell.
I've got a UITableViewController with a custom cell view. I created an empty Interface Builder document, then added a Table View Cell, then added a label to it. The Table View Cell has a corresponding class that extends UITableViewCell. The Table View Cell's label in Interface Builder is linked (outet) to the var in my custom class
class MyTableViewCell: UITableViewCell {
#IBOutlet var someLabel: UILabel!
The problem is that the the custom cell never renders, it's always blank (I tried the background color trick too). I never see the label. In fact the label is always null.
In my UITableViewController's viewDidLoad(), I've tried
let nib = UINib(nibName: "MyTableCellView", bundle: nil)
tableView.registerNib(nib, forCellReuseIdentifier: "myCell")
as well as
tableView.registerClass(MyTableViewCell.self, forCellReuseIdentifier: "myCell")
I also have
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as! MyTableViewCell
print("cellForRowAtIndexPath, cell = \(cell), someLabel = \(cell.someLabel)")
return cell
}
At runtime it is dequeueing as cell is non-null, however cell.someLabel is nil.
What does it take to have a custom table view cell render?
someLabel has no value. Try:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as! MyTableViewCell
cell.someLabel.text = "Put label text here"
return cell
}
I usually do this way. I load the xib file within the custom table view cell class.
class MyTableViewCell: UITableViewCell {
#IBOutlet weak var label: UILabel!
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
xibSetup()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
xibSetup()
}
func xibSetup() {
cell = loadViewFromNib()
cell.frame = self.bounds
cell.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
addSubview(cell)
}
func loadViewFromNib() -> UITableViewCell {
let bundle = NSBundle(forClass: self.dynamicType)
let nib = UINib(nibName: "MyTableViewCell", bundle: bundle)
let cell = nib.instantiateWithOwner(self, options: nil)[0] as! UITableViewCell
return cell
}
}
Along with:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as! MyTableViewCell
print("cellForRowAtIndexPath, cell = \(cell), someLabel = \(cell.someLabel)")
return cell
}
One other thing to do is to set the File's Owner in MyTableViewCell.xib file to MyTableViewCell class.
My TapCell1.swift
This is Custom UITableViewCell View
import UIKit
class TapCell1: UITableViewCell
{
#IBOutlet var labelText : UILabel
init(style: UITableViewCellStyle, reuseIdentifier: String!)
{
println("Ente")
super.init(style: UITableViewCellStyle.Value1, reuseIdentifier: reuseIdentifier)
}
override func setSelected(selected: Bool, animated: Bool)
{
super.setSelected(selected, animated: animated)
}
}
My ViewController.swift
Its All DataSource and Delegates are set correctly.But My custom Cell is not displaying.
import UIKit
class NextViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
{
#IBOutlet var label: UILabel
#IBOutlet var tableView : UITableView
var getvalue = NSString()
override func viewDidLoad()
{
super.viewDidLoad()
label.text="HELLO GOLD"
println("hello : \(getvalue)")
self.tableView.registerClass(TapCell1.self, forCellReuseIdentifier: "Cell")
}
func tableView(tableView:UITableView!, numberOfRowsInSection section:Int)->Int
{
return 5
}
func numberOfSectionsInTableView(tableView:UITableView!)->Int
{
return 1
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
{
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as TapCell1
cell.labelText.text="Cell Text"
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The Problem is My custom cell is Not displayed. Please suggest anything i did wrong.
Note: here is My code My File Download Link
I finally did it.
For TapCell1.swift
import UIKit
class TapCell1: UITableViewCell {
#IBOutlet var labelTitle: UILabel
init(style: UITableViewCellStyle, reuseIdentifier: String!) {
super.init(style: UITableViewCellStyle.Value1, reuseIdentifier: reuseIdentifier)
}
}
For NextViewController.swift
import UIKit
class NextViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var tableView: UITableView
var ListArray=NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
let nibName = UINib(nibName: "TapCell1", bundle:nil)
self.tableView.registerNib(nibName, forCellReuseIdentifier: "Cell")
for i in 0...70 {
ListArray .addObject("Content: \(i)")
}
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int)->Int {
return ListArray.count
}
func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 51
}
func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
return 1
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as TapCell1
//cell.titleLabel.text = "\(ListArray.objectAtIndex(indexPath.item))"
cell.labelTitle.text = "\(ListArray.objectAtIndex(indexPath.row))"
return cell
}
}
My working code link: CUSTOMISED TABLE
You should register the class for the cell. For that do
change this line of code to
self.tableView.registerClass(TapCell1.classForCoder(), forCellReuseIdentifier: "Cell")
Edit
You code is looks fine i checked it
//cell.labelText.text="Cell Text"
cell.textLabel.text="Cell Text" // use like this
The solution is most likely pinpointed to setting the cell height manually as such:
override func tableView(tableView:UITableView!, heightForRowAtIndexPath indexPath:NSIndexPath)->CGFloat
{
return 44
}
I believe it's an Xcode beta 6 bug.
I have now been able to get Custom UITableViewCell to work.
Works on
Runs on Xcode 6 beta 6
Runs on Xcode 6 beta 5
iOS is 7.1
How
I have created a ".xib" file for the cell.
I copy it into the storyboard.
Via the storyboard I give it a Identifier.
I make sure it is a sub child of a tableview
Doing it this way, you do not need to register a class / nib etc.
This is my custom cell.
import UIKit
class TestCell: UITableViewCell {
#IBOutlet var titleImageView: UIImageView!
#IBOutlet var titleLabel: UILabel!
override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
In your view, or where ever you extend "UITableViewDataSource".
Make sure "cell2" is the same as the "Identifier" that you gave it via the storyboard.
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell:TestCell = tableView.dequeueReusableCellWithIdentifier("cell2", forIndexPath: indexPath) as TestCell
// Example of using the custom elements.
cell.titleLabel.text = self.items[indexPath.row]
var topImage = UIImage(named: "fv.png")
cell.titleImageView.image = topImage
return cell
}
uitableviewcell
Check your Story board select the cell and look at the "identity inspector in that select CLASS type your CustomClass and MODULE type your project name
I have done this It works perfectly try this tip to avoid error to see below image and code
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
// let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: nil)
// cell.textLabel.text = array[indexPath!.row] as String
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as CustomTableViewCell
cell.nameLabel.text = array[indexPath!.row] as String
cell.RestaurentView.image = UIImage(named:images[indexPath!.row])
return cell
}
Try this following code
var cell:CustomTableViewCell = tableView.dequeueReusableCellWithIdentifier("CustomTableViewCell") as CustomTableViewCell
https://github.com/iappvk/TableView-Swift
If you are not using Storyboard then create a new file as subclass of UITableViewCell check the checkbox "also create xib files" after that set your custom cell .and here is the code for tableview
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var customcell:CustomTableViewCellClass? = tableView.dequeueReusableCellWithIdentifier("cell") as? CustomTableViewCellClass
if (customcell==nil)
{
var nib:NSArray=NSBundle.mainBundle().loadNibNamed("CustomTableViewCellClass", owner: self, options: nil)
customcell = nib.objectAtIndex(0) as? CustomTableViewCell
}
return customcell!
}
Try this following code:
var cell = tableView.dequeueReusableCell(withIdentifier: "CustomCellTableView") as? CustomCellTableView
Extention of NSOject
extension NSObject {
var name: String {
return String(describing: type(of: self))
}
class var name: String {
return String(describing: self)
}
}
Properties on Custom TableViewCell
class var nib: UINib {
return UINib(nibName:YourTableViewCell.name, bundle: nil)
}
class var idetifier: String {
return YourTableViewCell.name
}
Add in UIViewController
self.tableView.registerNib(YourTableViewCell.nib, forCellReuseIdentifier: YourTableViewCell.idetifier)
let cell = tableView.dequeueReusableCellWithIdentifier(YourTableViewCell.idetifier, forIndexPath: indexPath) as! YourTableViewCell
It is Purely swift notation an working for me
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cellIdentifier:String = "CustomFields"
var cell:CustomCell? = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? CustomCell
if (cell == nil)
{
var nib:Array = NSBundle.mainBundle().loadNibNamed("CustomCell", owner: self, options: nil) cell = nib[0] as? CustomCell
}
return cell!
}