將 UITableView 的代理方法與 ViewController 分離是一個常見的開發(fā)模式,有助于遵循 單一職責原則 (SRP) 和提升代碼的可維護性??梢酝ㄟ^以下幾種方式實現(xiàn)這一點:
1. 創(chuàng)建單獨的代理類
可以定義一個獨立的類來處理 UITableView 的 DataSource 和 Delegate,并在 ViewController 中進行實例化和關(guān)聯(lián)。
示例代碼
import UIKit
// 自定義代理類
class TableViewHandler: NSObject, UITableViewDataSource, UITableViewDelegate {
? ? private var data: [String]
? ?
? ? init(data: [String]) {
? ? ? ? self.data = data
? ? }
? ? // MARK: - UITableViewDataSource
? ? func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
? ? ? ? return data.count
? ? }
? ? func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
? ? ? ? let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
? ? ? ? cell.textLabel?.text = data[indexPath.row]
? ? ? ? return cell
? ? }
? ? // MARK: - UITableViewDelegate
? ? func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
? ? ? ? print("Selected row: \(data[indexPath.row])")
? ? }
}
// ViewController
class ViewController: UIViewController {
? ? @IBOutlet weak var tableView: UITableView!
? ? private var tableViewHandler: TableViewHandler!
? ? override func viewDidLoad() {
? ? ? ? super.viewDidLoad()
? ? ? ? // 初始化數(shù)據(jù)
? ? ? ? let data = ["Item 1", "Item 2", "Item 3"]
? ? ? ? tableViewHandler = TableViewHandler(data: data)
? ? ? ? // 設(shè)置代理
? ? ? ? tableView.dataSource = tableViewHandler
? ? ? ? tableView.delegate = tableViewHandler
? ? ? ?
? ? ? ? // 注冊Cell
? ? ? ? tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
? ? }
}
2. 使用協(xié)議回調(diào)傳遞事件
如果需要在 ViewController 中處理 UITableView 的某些事件,可以通過協(xié)議回調(diào)實現(xiàn)。
示例代碼
// 定義協(xié)議
protocol TableViewHandlerDelegate: AnyObject {
? ? func didSelectItem(_ item: String)
}
class TableViewHandler: NSObject, UITableViewDataSource, UITableViewDelegate {
? ? private var data: [String]
? ? weak var delegate: TableViewHandlerDelegate?
? ? init(data: [String]) {
? ? ? ? self.data = data
? ? }
? ? // MARK: - UITableViewDataSource
? ? func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
? ? ? ? return data.count
? ? }
? ? func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
? ? ? ? let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
? ? ? ? cell.textLabel?.text = data[indexPath.row]
? ? ? ? return cell
? ? }
? ? // MARK: - UITableViewDelegate
? ? func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
? ? ? ? delegate?.didSelectItem(data[indexPath.row])
? ? }
}
// ViewController
class ViewController: UIViewController, TableViewHandlerDelegate {
? ? @IBOutlet weak var tableView: UITableView!
? ? private var tableViewHandler: TableViewHandler!
? ? override func viewDidLoad() {
? ? ? ? super.viewDidLoad()
? ? ? ? // 初始化數(shù)據(jù)
? ? ? ? let data = ["Item 1", "Item 2", "Item 3"]
? ? ? ? tableViewHandler = TableViewHandler(data: data)
? ? ? ? tableViewHandler.delegate = self
? ? ? ? // 設(shè)置代理
? ? ? ? tableView.dataSource = tableViewHandler
? ? ? ? tableView.delegate = tableViewHandler
? ? ? ?
? ? ? ? // 注冊Cell
? ? ? ? tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
? ? }
? ? // MARK: - TableViewHandlerDelegate
? ? func didSelectItem(_ item: String) {
? ? ? ? print("Selected item: \(item)")
? ? }
}
3. 使用 Swift 的閉包回調(diào)
可以在 TableViewHandler 中定義閉包,直接在 ViewController 中傳遞事件。
示例代碼
class TableViewHandler: NSObject, UITableViewDataSource, UITableViewDelegate {
? ? private var data: [String]
? ? var didSelectItem: ((String) -> Void)?
? ? init(data: [String]) {
? ? ? ? self.data = data
? ? }
? ? // MARK: - UITableViewDataSource
? ? func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
? ? ? ? return data.count
? ? }
? ? func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
? ? ? ? let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
? ? ? ? cell.textLabel?.text = data[indexPath.row]
? ? ? ? return cell
? ? }
? ? // MARK: - UITableViewDelegate
? ? func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
? ? ? ? didSelectItem?(data[indexPath.row])
? ? }
}
// ViewController
class ViewController: UIViewController {
? ? @IBOutlet weak var tableView: UITableView!
? ? private var tableViewHandler: TableViewHandler!
? ? override func viewDidLoad() {
? ? ? ? super.viewDidLoad()
? ? ? ? // 初始化數(shù)據(jù)
? ? ? ? let data = ["Item 1", "Item 2", "Item 3"]
? ? ? ? tableViewHandler = TableViewHandler(data: data)
? ? ? ? tableViewHandler.didSelectItem = { item in
? ? ? ? ? ? print("Selected item: \(item)")
? ? ? ? }
? ? ? ? // 設(shè)置代理
? ? ? ? tableView.dataSource = tableViewHandler
? ? ? ? tableView.delegate = tableViewHandler
? ? ? ?
? ? ? ? // 注冊Cell
? ? ? ? tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
? ? }
}
對比與選擇
? 單獨的代理類:適合簡單列表邏輯。
? 協(xié)議回調(diào):適合復(fù)雜交互且需要強解耦時使用。
? 閉包回調(diào):語法簡潔,適合快速實現(xiàn)簡單交互。
根據(jù)需求選擇合適的方案即可。