2016-10-24 39 views
14

我是Swift和iOS開發的新手,我嘗試以編程方式實現UITableView,而不使用xib或Storyboard。這是我的代碼:以編程方式在Swift中創建UITableView

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

但是當我運行的應用程序,我得到的是空表。在日誌中我看到幾行sectionsrows,但沒有get cell。我該如何解決這個代碼以獲得6行foo文本的表格?

+3

爲什麼你有一個'ViewController'與它自己的表視圖和一個'MyTableViewController',它也有它自己的表視圖? – rmaddy

+2

''ViewTidLoad'後發佈'MyTableViewController'。所以請儘量保留一個參考。 –

+0

如果您是iOS和Swift的新手,我強烈建議您在網絡或iTunesU上查看教程。關於iTunesU的斯坦福大學課程叫做「用Swift開發iOS 9應用程序」將解釋關於對象圖以及如何使用iOS框架。 –

回答

29

注意:正如你所說,你剛開始編程Swift 3。我編程創建了一個tableView。 Copypaste下面的代碼在您的viewController運行該項目...

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

輸出:

enter image description here

3

您使用UITableViewController作爲視圖控制器的表視圖的數據源和委託是沒有意義的。您自己的視圖控制器應該是表視圖的數據源和委託。

因爲你似乎想用一個表視圖的視圖控制器,不佔用整個視圖,每一件事情轉移到您的視圖控制器如下:

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

我認爲OP想要創建一個遠離VC的結構(或數據模型)? – aremvee

1

你不需要爲UITableView創建一個單獨的類。只需在你的ViewController類中實現UITableViewDelegate和UITableViewDataSource的協議,然後實現委託方法。 我覺得你的代碼應該像

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

告訴我們更多信息或顯示日誌,如果你仍然面臨的問題。

10

更新了夫特3

選項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") 
    } 
} 

選項2:代替上述選項1個 TableViewController與此類

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

+0

如果你不想要頁眉或頁腳,只是刪除各自的標記代碼並評論tableView.register行。 – iajmeri43

+0

對於選項2,在swift 4中,在tableView聲明中添加委託和dataSource(例如tv.dataSource = self)引發錯誤。相反,我必須在viewDidLoad方法中定義dataSource和委託。 –

+1

@GeorgeBikas善待懶惰var tableView,而不是讓tableView然後它工作... – iajmeri43

0

斯威夫特4兼容

而不是增加一個UITableViewUIViewController的,你應該考慮創建UITableViewController並避免設置代表:

class YourTVC: TableViewController { 

    override func viewDidLoad() { 
    super.viewDidLoad() 

    // setup stuff 
    tableView.register(UITableViewCell.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) 
    cell.textLabel?.text = "Cell at row \(indexPath.row)" 
    return cell 
    } 

} 
相關問題