Well, I am trying to make the headers of UITableView compatible with iPhone X Landscape where I want background colors of Header should expand to edge.
I have seen the WWDC video to do that where they said to apply color on backgroundView but in my case it's always nil.
Here is my code and also link to demo of it.
extension ViewController:UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return 5
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: String.init(describing: HVTableViewCell.self)) as! HVTableViewCell
return cell
}
}
extension ViewController:UITableViewDelegate{
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 60.0
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 44.0
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: String.init(describing: HVTableViewHeaderFooterView.self)) as? HVTableViewHeaderFooterView{
if let backgroundView = headerView.backgroundView{
backgroundView.backgroundColor = UIColor.red
}else{
print("Failed")
}
return headerView
}else{
return nil
}
}
}
class ViewController: UIViewController {
#IBOutlet weak var tblReference: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tblReference.register(UINib.init(nibName: String.init(describing: HVTableViewCell.self), bundle: nil), forCellReuseIdentifier: String.init(describing: HVTableViewCell.self))
self.tblReference.register(UINib.init(nibName: String.init(describing: HVTableViewHeaderFooterView.self), bundle: nil), forHeaderFooterViewReuseIdentifier: String.init(describing: HVTableViewHeaderFooterView.self))
self.tblReference.delegate = self
self.tblReference.dataSource = self
self.tblReference.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Here is the screenshot of the issue.
Thanks in advance.
I found another way to do it.
We can set the background color of Layer of HeaderView.
// HeaderView Class
self.layer.backgroundColor = UIColor.red.cgColor
Here is the link of working code.
Hope it helps to others as well.
Related
There are questions and answers for how to change the background color of Header titles in UITableView. These work when a class directly inherits from UITableView. However, when I embed a UITableView as a child of a UIViewController, the same approach of changing the background color does not appear to work.
Can you please see the code below and let me know how I can do this?
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var table: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = "Test row"
return cell
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "Section Title"
}
func numberOfSections(in tableView: UITableView) -> Int {
1
}
// One way to change the header color
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
view.backgroundColor = .green
}
// Another way
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let vw = UIView()
vw.backgroundColor = .red
return vw
}
override func viewDidLoad() {
super.viewDidLoad()
table = UITableView(frame: CGRect(x: view.frame.maxX/3, y: view.frame.maxY/3, width: view.frame.width/2, height: view.frame.height/2))
table.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
table.dataSource = self
view.addSubview(table)
}
}
tableView(_:viewForHeaderInSection:) is a delegate method check Docs , so you need to add
table.delegate = self
You'll need to conform to UITableViewDelegate for titleForHeaderInSection, willDisplayHeaderView, and viewForHeaderInSection.
You'll need to conform to UITableViewDataSource for numberOfRowsInSection, cellForRowAt, numberOfRowsInSection.
In your viewDidLoad():
table.delegate = self
table.dataSource = self
I have set up tableview many times but don't why is not it showing anything. I have added a tableview on my storyboard file, added reference on ViewController file and set datasource and delegate on storyboard. on viewDidLoad registered the cell and finally added reusableIdentifier on TableViewCell. Here is my code with details configuration :
import UIKit
struct ViewControllerConstants {
static let kCellIdentifier = "TableViewCell"
static let kNibName = "TableViewCell"
}
class ViewController: UIViewController {
var cellImageNames : [String] = ["image1","image2","image3","image4","image5","image6"]
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tableView.register(UINib.init(nibName: ViewControllerConstants.kNibName, bundle: nil), forCellReuseIdentifier: ViewControllerConstants.kCellIdentifier)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
self.tableView.reloadData()
}
}
extension ViewController : UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellImageNames.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: ViewControllerConstants.kCellIdentifier, for: indexPath) as? TableViewCell {
cell.contentImageView.image = UIImage.init(named: cellImageNames[indexPath.row])
return cell
}
return UITableViewCell.init()
}
}
extension ViewController : UITableViewDelegate {
}
Try to remove identifiers for cells in storyboard.
Problem: Cell height was not defined on code. So it was creating cell with 0 height value .
Solution: Need to specify height of each row as below code:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
I not find what is my problem.
I need to give space between one cell and another.
I wrote self.tableView Storyline.delegate = self because I read that this could be the problem, but not know if it is correct.
This is my code:
class ClassName: UIViewController, UITableViewDataSource, UITabBarControllerDelegate, UITableViewDelegate {
public var notifications: [APINotification] = []
override func viewDidLoad() {
super.viewDidLoad()
self.tabBarController?.delegate = self
tableViewStoryline.rowHeight = UITableViewAutomaticDimension
tableViewStoryline.estimatedRowHeight = 140
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidAppear(_ animated: Bool) {
self.notifications = []
self.getLastNotifications()
APIAuth.shared.count_badge = 0
self.tabBarController?.tabBar.items![0].badgeValue = nil
}
public func getLastNotifications() {
let req = Notification()
req.getLastNotifications(onComplete: {events in
self.notifications = events
DispatchQueue.main.async(execute: {
self.tableViewStoryline.delegate = self
self.tableViewStoryline.dataSource = self
self.tableViewStoryline.sectionHeaderHeight = 10
self.tableViewStoryline.reloadData()
})
})
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
// There is just one row in every section
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if self.notifications.count > 4 {
return 4
} else {
return self.notifications.count
}
}
// Set the spacing between sections
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
cell = tableView.dequeueReusableCell(withIdentifier: "controller")! as UITableViewCell
titleLbl.text = notifications[indexPath.row].title
bodyLbl.text = notifications[indexPath.row].description
typeLbl.text = notifications[indexPath.row].type
return cell!
}
}
Does anyone have any idea what the problem is?
Is there some code missing?
Thanks!
I think this is what you want:
func numberOfSections(in tableView: UITableView) -> Int {
if self.notifications.count > 4 {
return 4
} else {
return self.notifications.count
}
}
// There is just one row in every section
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
Then you have to change also cellForRowAt to take this into account.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
cell = tableView.dequeueReusableCell(withIdentifier: "controller")! as UITableViewCell
titleLbl.text = notifications[indexPath.section].title
bodyLbl.text = notifications[indexPath.section].description
typeLbl.text = notifications[indexPath.section].type
return cell!
}
Instead of having one section with notifications.count rows, you want notifications.count sections and each section with one row. Now setting 10 points as height for section header will make cells appear as having spaces between them.
There are some other options that you can consider, see my other answer.
you are using wrong delegate function.
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
is used for the hieght of header not for height of cell.
use func tableView(UITableView, heightForRowAt: IndexPath)
you will get correct sized cells.
Hope this helps!
I have a UItableview cell that is contain a UItableview, I need to make height of that cell equal to height of it's child UItableview.
Image below explain what I need to do.
First see my ViewController,which has one tableview(tblview) and UITableViewCell(CustomTableViewCell) ,
class ViewController: UIViewController {
#IBOutlet var tblview:UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.tblview.delegate = self
self.tblview.dataSource = self
// 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.
}
}
extension ViewController:UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: CustomTableViewCell.identifier) as! CustomTableViewCell
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
}
Then see my CustomTableViewCell which has one table view and one label in a cell.See,
class CustomTableViewCell: UITableViewCell {
static let identifier = "CustomTableViewCell"
#IBOutlet var tblviewCell:UITableView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.tblviewCell.delegate = self
self.tblviewCell.dataSource = self
tblviewCell.isScrollEnabled = false
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize {
let heighToReturn = self.tblviewCell.contentSize.height + 20 // upper and down space
return CGSize(width: self.tblviewCell.contentSize.width, height: heighToReturn)
}
}
extension CustomTableViewCell:UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: customCell.identifier) as! customCell
cell.lblname?.text = "Vikas"
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
}
class customCell: UITableViewCell {
static let identifier = "customCell"
#IBOutlet weak var lblname :UILabel?
}
So, if you give tableview content size height in systemLayoutSizeFitting method then problem will be solve.
I hope this will help.
Here's how to do table header cells. The cell needs to be prototyped in the storyboard and subclassed (if needs to be configured). Then override the following funcs in the table view delegate. Alternatively, you can generate a view on the fly and return that from viewForHeaderInSection.
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 150
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerCell = tableView.dequeueReusableCell(withIdentifier: "ConferenceHeaderCell") as! ConferenceDetailHeaderCell
// configure cell
return headerCell
}
For the cells themselves, it's very similar:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ConferenceUserCell", for: indexPath) as! ConferenceDetail_TVCell
// Configure the cell...
return cell
}
and depending, you may to implement 'heightForRowAtIndexPath'
I try to implement UITableView programmatically without use of xib or Storyboards. This is my code:
ViewController.swift
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let table: UITableViewController = MyTableViewController()
let tableView: UITableView = UITableView()
tableView.frame = CGRect(x: 10, y: 10, width: 100, height: 500)
tableView.dataSource = table
tableView.delegate = table
self.view.addSubview(tableView)
}
}
MyTableViewController.swift
import UIKit
class MyTableViewController: UITableViewController {
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
NSLog("sections")
return 2
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
NSLog("rows")
return 3
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
NSLog("get cell")
let cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Cell")
cell.textLabel!.text = "foo"
return cell
}
}
But when I run app, all I get is empty table. In log I see a few lines of sections and rows, but no get cell. How can I fix this code to get table with 6 lines of foo text?
Note: As you mentioned you just started programming in Swift. I created a tableView programmatically. Copy and paste below code into your viewController and run the project...
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
private let myArray: NSArray = ["First","Second","Third"]
private var myTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
let barHeight: CGFloat = UIApplication.shared.statusBarFrame.size.height
let displayWidth: CGFloat = self.view.frame.width
let displayHeight: CGFloat = self.view.frame.height
myTableView = UITableView(frame: CGRect(x: 0, y: barHeight, width: displayWidth, height: displayHeight - barHeight))
myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
myTableView.dataSource = self
myTableView.delegate = self
self.view.addSubview(myTableView)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Num: \(indexPath.row)")
print("Value: \(myArray[indexPath.row])")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath as IndexPath)
cell.textLabel!.text = "\(myArray[indexPath.row])"
return cell
}
}
Output:
Updated for Swift 3
Option 1:
import UIKit
//
// MARK :- TableViewController
//
class TableViewController: UITableViewController {
private let headerId = "headerId"
private let footerId = "footerId"
private let cellId = "cellId"
//
// MARK :- HEADER
//
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 150
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerId) as! CustomTableViewHeader
return header
}
//
// MARK :- FOOTER
//
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 150
}
override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footer = tableView.dequeueReusableHeaderFooterView(withIdentifier: footerId) as! CustomTableViewFooter
return footer
}
//
// MARK :- CELL
//
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! CustomTableCell
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
title = "TableView Demo"
view.backgroundColor = .white
setupTableView()
}
func setupTableView() {
tableView.backgroundColor = .lightGray
tableView.register(CustomTableViewHeader.self, forHeaderFooterViewReuseIdentifier: headerId)
tableView.register(CustomTableViewFooter.self, forHeaderFooterViewReuseIdentifier: footerId)
tableView.register(CustomTableCell.self, forCellReuseIdentifier: cellId)
}
}
//
// MARK :- HEADER
//
class CustomTableViewHeader: UITableViewHeaderFooterView {
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
contentView.backgroundColor = .orange
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//
// MARK :- FOOTER
//
class CustomTableViewFooter: UITableViewHeaderFooterView {
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
contentView.backgroundColor = .green
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//
// MARK :- CELL
//
class CustomTableCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.backgroundColor = .white
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Option 2: replace above Option 1 TableViewController with this class
import UIKit
//
// MARK :- ViewController
//
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
private let headerId = "headerId"
private let footerId = "footerId"
private let cellId = "cellId"
lazy var tableView: UITableView = {
let tv = UITableView(frame: .zero, style: .plain)
tv.translatesAutoresizingMaskIntoConstraints = false
tv.backgroundColor = .lightGray
tv.delegate = self
tv.dataSource = self
tv.register(CustomTableViewHeader.self, forHeaderFooterViewReuseIdentifier: self.headerId)
tv.register(CustomTableViewFooter.self, forHeaderFooterViewReuseIdentifier: self.footerId)
tv.register(CustomTableCell.self, forCellReuseIdentifier: self.cellId)
return tv
}()
//
// MARK :- HEADER
//
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 150
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerId) as! CustomTableViewHeader
return header
}
//
// MARK :- FOOTER
//
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 150
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footer = tableView.dequeueReusableHeaderFooterView(withIdentifier: footerId) as! CustomTableViewFooter
return footer
}
//
// MARK :- CELL
//
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! CustomTableCell
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
title = "TableView Demo"
view.backgroundColor = .white
view.addSubview(tableView)
setupAutoLayout()
}
func setupAutoLayout() {
tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
}
Swift 4 compatible
Instead of adding a UITableView to your UIViewController, you should consider creating a UITableViewController and avoid setting up delegates:
class YourTVC: TableViewController {
override func viewDidLoad() {
super.viewDidLoad()
// setup custom cells if you use them
tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "yourCell")
}
// MARK: tableView
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3 // set to value needed
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "yourCell", for: indexPath) as! CustomTableViewCell
cell.textLabel?.text = "Cell at row \(indexPath.row)"
return cell
}
}
It makes no sense that you are using a UITableViewController as the data source and delegate for your view controller's table view. Your own view controller should be the table view's data source and delegate.
Since you seem to want a view controller with a table view that doesn't take up the entire view, move every thing to your view controller as follows:
ViewController.swift:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let tableView: UITableView = UITableView()
tableView.frame = CGRect(x: 10, y: 10, width: 100, height: 500)
tableView.dataSource = self
tableView.delegate = self
self.view.addSubview(tableView)
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
NSLog("sections")
return 2
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
NSLog("rows")
return 3
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
NSLog("get cell")
let cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Cell")
cell.textLabel!.text = "foo"
return cell
}
}
You don't need to make a separate class for UITableView. Just in your ViewController class implement protocols of UITableViewDelegate and UITableViewDataSource and then implement delegate methods.
I think your code should be like
class ViewController: UIViewController , UITableViewDelegate , UITableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
let table: UITableViewController = MyTableViewController()
let tableView: UITableView = UITableView()
tableView.frame = CGRect(x: 10, y: 10, width: 100, height: 500)
tableView.dataSource = table
tableView.delegate = table
self.view.addSubview(tableView)
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
NSLog("sections")
return 2
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
NSLog("rows")
return 3
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
NSLog("get cell")
let cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Cell")
cell.textLabel!.text = "foo"
return cell
}
}
Tell us more info or show logs if you still face issue.
I had a similar issue in that the data would not populate for my programmatic UITableView. This was because I was using a delegate/dataSource without a strong reference. Once I kept a reference to it (I had one class implementing both UITableViewDataSource and UITableViewDelegate), the data was populated.
import UIKit
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(TableCell.self, forCellReuseIdentifier: "cell")
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableCell
cell.nameLabel.text = "TableViewCell programtically"
cell.nameLabel.textAlignment = .center
cell.nameLabel.textColor = .white
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
}
Simple solution
import UIKit
class CustomTableViewController: UICollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath)
cell.textLabel!.text = "\(indexPath.row)"
return cell
}
}