Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create UITableView programmatically in Swift

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?

like image 688
Ondra Avatar asked Oct 24 '16 14:10

Ondra


People also ask

What is UITableView in Swift?

A view that presents data using rows in a single column. iOS 2.0+ iPadOS 2.0+ Mac Catalyst 13.1+ tvOS 9.0+

How do I populate UITableView?

There are two main base ways to populate a tableview. The more popular is through Interface Building, using a prototype cell UI object. The other is strictly through code when you don't need a prototype cell from Interface Builder.

What is difference between tableView and Collectionview?

Table view presents data in multiple rows arranged in a single column, the cell design is fit as a row. However, collection view can create rows and columns, it can design cells in various ways, even if they are not necessarily rows. It's also the biggest feature of a collection view cell.


Video Answer


2 Answers

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:

enter image description here

like image 77
Joe Avatar answered Sep 19 '22 15:09

Joe


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     } } 

enter image description here

like image 39
iAj Avatar answered Sep 19 '22 15:09

iAj