Create UITableView programmatically in Swift

前端 未结 8 1301
青春惊慌失措
青春惊慌失措 2020-12-12 12:00

I try to implement UITableView programmatically without use of xib or Storyboards. This is my code:

ViewController.swift

import UIKi         


        
相关标签:
8条回答
  • 2020-12-12 12:54

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

    0 讨论(0)
  • 2020-12-12 12:54

    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.

    0 讨论(0)
提交回复
热议问题