将动画构建到UITableView的子类中
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将动画构建到UITableView的子类中相关的知识,希望对你有一定的参考价值。
我创建了一个我非常喜欢的表视图 - 它在委托函数tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
中播放了一些不错的动画。
麻烦的是,我找不到在我的代码库中的其他地方复制该行为的方法,而无需复制并粘贴委托函数中的代码并违反DRY。我希望能够从一个地方调整项目中所有tableviews的动画参数。
- 首先,我尝试编写
UITableView
的子类,但这并不好,因为动画是在委托函数中指定的。您可以使子类成为自己的委托并定义所需的行为,但是其所有其他委托函数都不可用于其包含的视图。 - 我考虑编写一个继承自
UITableViewDelegate
的协议,但是你必须重新实现协议中的每个tableview委托函数,即使其中只有一个是不同的。 - 我想过试图调用willDisplayCell函数,但我不确定它是否会起作用,如果我远离它,我真的不想乱七八糟。
我怎么能把这样的东西拉下来?在这个非常具体的情况下,以及更普遍的OOP意义上,想要为委托函数提供默认行为而不必将类设置为自己的委托?
答案
您不应该是UITableView的子类,也不应该是swizzle,也不应该扩展委托协议。
我要做的是编写一个实现和包装委托方法的类。这个类可以拥有它自己的委托,但我宁愿给它封闭来调用。
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))")
}
}
}
另一答案
创建UIViewController
子类所有动画tableViews继承自:
class BaseAnimatedTableViewController: UIViewController, UICollectionViewDelegate {
var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView = UITableView
//setupTableView
tableView.delegatge = self
}
//override delegate methods, that all subclasses should share
}
并为每个动画tableView子类化:
class AnimatedTableView1: BaseAnimatedTableViewController, UITableViewDataSource {
...
}
class AnimatedTableView2: BaseAnimatedTableViewController, UITableViewDataSource {
...
}
你当然也可以继承UITableViewController
而不是UIViewController
。
以上是关于将动画构建到UITableView的子类中的主要内容,如果未能解决你的问题,请参考以下文章
UITableView reloadData 在编辑和保留动画时