你不應該繼承UITableView,也不要調試或擴展委託協議。
我會做的是編寫一個實現和包裝委託方法的類。這個類可以有它自己的委託,但我寧願給它閉包來打電話。
class TableViewDelegate: UITableViewDeleagte {
var willDisplayCell: ((UITableView, UITableViewCell, IndexPath) -> Void)?
let animator: Animator
weak var tableView: UITableView? {
didSet {
tableView?.delegate = self
}
}
init(tableView: UITableView, animator: Animator) {
self.animator = animator
}
func tableView(_ tableView: UITableView, willDisplay cell: UItableViewCell, forRowAt indexPath: IndexPath) {
animator.animate(cell)
willDisplayCell?(tableView, cell, indexPath)
}
}
一個完整的例子:
protocol AnimatorType {
func animate(view: UIView)
}
class Animator: AnimatorType {
func animate(view: UIView) {
view.transform = CGAffineTransform(translationX: -30, y: 0)
UIView.animate(withDuration: 0.3, animations: {
view.transform = CGAffineTransform.identity
})
}
}
class TableViewDataSource:NSObject, UITableViewDataSource {
let data = Array(0 ..< 30).map{ $0 * $0 }
init(tableView: UITableView) {
self.tableView = tableView
super.init()
tableView.dataSource = self
}
weak var tableView: UITableView?
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell1", for: indexPath)
let v = data[indexPath.row]
cell.textLabel?.text = "\(v)"
return cell
}
func object(at indexPath: IndexPath) -> Int{
return self.data[indexPath.row]
}
}
class TableViewDelegate:NSObject, UITableViewDelegate {
var willDisplayCell: ((UITableView, UITableViewCell, IndexPath) -> Void)?
var didSelectCell: ((UITableView, IndexPath) -> Void)?
let animator: AnimatorType
weak var tableView: UITableView?
init(tableView: UITableView, animator: AnimatorType) {
self.tableView = tableView
self.animator = animator
super.init()
tableView.delegate = self
}
private var highestIndexPath = IndexPath(row: -1, section: 0)
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row > highestIndexPath.row {
animator.animate(view: cell)
highestIndexPath = indexPath
}
willDisplayCell?(tableView, cell, indexPath)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
didSelectCell?(tableView, indexPath)
}
}
class ViewController: UIViewController {
var tableViewDataSource: TableViewDataSource?
var tableViewDelegate: TableViewDelegate?
let animator = Animator()
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.tableViewDataSource = TableViewDataSource(tableView: tableView)
self.tableViewDelegate = TableViewDelegate(tableView: tableView, animator: animator)
self.tableViewDelegate?.didSelectCell = {
[weak self] tableView, indexPath in
guard let `self` = self else { return }
print("selected: \(self.tableViewDataSource!.object(at: indexPath))")
}
}
}
在實際項目中,我將實現在一個類中的委託和數據源,因爲這將讓我有一個返回選定數據對象單封閉呼叫。的確我寫了一個(objective-c)框架來設計這樣的類,叫做OFAPopulator。
請把你想要的屏幕排序。 – Sanjukta
我不確定截圖會有多大幫助,但希望它能讓我想要做得更清楚。 – Erik