簡體   English   中英

UITableView 如何與 UITableViewDataSource 配合使用?

[英]How does UITableView work with UITableViewDataSource?

我是 Swift 的新手,我正在嘗試了解tableView.dataSource = self如何與擴展中的功能相關:

class ChatViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var messageTextfield: UITextField!

    var messages: [Message] = [
        Message(sender: "email", body: "Hey!" ),
        Message(sender: "email", body: "Hello!" ),
        Message(sender: "email", body: "What's up!" ),
    ]

    override func viewDidLoad() {
        super.viewDidLoad()
        title = K.appName
        navigationItem.hidesBackButton = true
        tableView.dataSource = self
    }

    @IBAction func sendPressed(_ sender: UIButton) {
    }


    @IBAction func logOutPressed(_ sender: UIBarButtonItem) {
        do {
          try Auth.auth().signOut()
            navigationController?.popToRootViewController(animated: true)
        } catch let signOutError as NSError {
          print ("Error signing out: %@", signOutError)
        }
    }
}


extension ChatViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print(section)
        return messages.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: K.cellIdentifier, for: indexPath)
        cell.textLabel?.text = messages[indexPath.row].body
        return cell
    }
}

tableView.dataSource是來自 storyboard 的變量,它與名為tableView的擴展中定義的兩個函數不同,后者恰好具有相同的名稱。 變量tableView作為第一個參數傳遞給兩個函數tableView並且沒有在定義中使用。

變量tableView和 function tableView之間的關系是什么以及如何在 function 中使用該變量,即使它不在 ZC1C425268E68385D14AB5074C17Z9 的定義中? tableView.dataSource = self是做什么的?

UIKit中的許多類都使用這種“數據源”模式來填充自己的數據。 除了UITableView ,還有UICollectionViewUIPickerViewUIPageViewControllerDataSource ,僅舉幾例。 這個答案中所說的也可以應用於這些課程。


UITableView不會讓您一次性提供所有數據,而是僅在需要時才請求數據。 這是因為有時數據可能在 Internet 上,一次獲取所有數據可能需要很長時間,不是嗎?

好的,那么表格視圖應該向誰詢問數據? dataSource 表視圖如何知道它的數據源可以回答它的問題? 通過確保數據源符合UITableViewDataSource協議,該協議定義了一堆方法。

因此, tableView.dataSource = self是說:

tableView ,如果你想問數據,問selfChatViewController )!

通過實現UITableViewDataSource ,我們說這個 class能夠為表格視圖的問題提供答案

我們如何實際提供答案? 通過實現數據源方法!

// this is asking:
// for section number "section" the table view "tableView", how many rows does it have?
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    print(section)
    return messages.count // we answer: it has as many rows as "messages.count"
}

// this is asking:
// for the row at the index path "indexPath", in the table view "tableView",
// what UITableViewCell should I display?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: K.cellIdentifier, for: indexPath)
    cell.textLabel?.text = messages[indexPath.row].body
    return cell // we answer: you should display this cell!
}

注意,雖然上面的兩個數據源方法確實有tableView這個名字,但是將它們稱為numberOfRowsInSectioncellForRowAt會更有用,這也是人們經常做的事情。

不太重要(對於這個問題),在這些方法中, tableView指的是參數,而不是 class 中聲明的屬性。 要引用 class 中聲明的屬性,您需要self.tableView

表格視圖將在適當的時候調用這些方法,同時提供參數。 例如, cellForRowAt將在需要顯示新單元格時被調用。

我發現你對你的一些誤解:

tableView.dataSource是來自 storyboard 的變量

dataSource屬性UITableView中聲明。 您只能在 storyboard(或更准確地說,Xcode 的 Interface Builder)中看到它。 dataSource並不是真正“來自”storyboard。

變量tableView作為第一個參數傳遞給兩個函數tableView並且沒有在定義中使用。

這個tableView就是參數的名字。 你沒有通過任何東西。 請記住,您正在聲明這些方法,並且您不應該傳遞參數。 調用者 - 表視圖 - 是。

此外,您在cellForRowAt使用tableView參數,因為該參數隱藏了ChatViewController中聲明的tableView屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM