将 UITableView 的代理方法与 ViewController 分离是一个常见的开发模式,有助于遵循 单一职责原则 (SRP) 和提升代码的可维护性。可以通过以下几种方式实现这一点:
1. 创建单独的代理类
可以定义一个独立的类来处理 UITableView 的 DataSource 和 Delegate,并在 ViewController 中进行实例化和关联。
示例代码
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()
// 初始化数据
let data = ["Item 1", "Item 2", "Item 3"]
tableViewHandler = TableViewHandler(data: data)
// 设置代理
tableView.dataSource = tableViewHandler
tableView.delegate = tableViewHandler
// 注册Cell
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
}
2. 使用协议回调传递事件
如果需要在 ViewController 中处理 UITableView 的某些事件,可以通过协议回调实现。
示例代码
// 定义协议
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()
// 初始化数据
let data = ["Item 1", "Item 2", "Item 3"]
tableViewHandler = TableViewHandler(data: data)
tableViewHandler.delegate = self
// 设置代理
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 的闭包回调
可以在 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()
// 初始化数据
let data = ["Item 1", "Item 2", "Item 3"]
tableViewHandler = TableViewHandler(data: data)
tableViewHandler.didSelectItem = { item in
print("Selected item: \(item)")
}
// 设置代理
tableView.dataSource = tableViewHandler
tableView.delegate = tableViewHandler
// 注册Cell
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
}
对比与选择
• 单独的代理类:适合简单列表逻辑。
• 协议回调:适合复杂交互且需要强解耦时使用。
• 闭包回调:语法简洁,适合快速实现简单交互。
根据需求选择合适的方案即可。