我一直在尝试找出如何在不需要外部数组的情况下将动画应用于表格视图的单元格。我希望动画仅在用户向下滚动时发生一次,但是在用户向下滑动以重新加载数据时重置。我在自定义单元格类定义中选择了一个布尔变量animatedAlready,它可以工作,但是动画注册得非常快,并且动画显示不一致。另外,我正在努力寻找一种方法来刷新表视图时重置每个单元格中的animatedAlready的值...
conda create --name snowflakes wordcloud
以及我当前尝试重新加载动画的时间:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
//If transactionPage is set to -1, it's because we've reached the end of the transactions
if transactionPage != -1 && indexPath.row == (tableData.rows(inSection: indexPath.section).count) - 1 {
loadMoreTransactions()
}
if let cell = cell as? CustomCell, !cell.animatedAlready {
cell.alpha = 0
cell.animatedAlready = true
//Slide from bottom
let transform = CATransform3DTranslate(CATransform3DIdentity, 0, 200, 0)
cell.layer.transform = transform
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
cell.alpha = 1
cell.layer.transform = CATransform3DIdentity
})
}
}
扩展名(我完全知道这是错误的,只是想不起其他任何东西):
@objc func reloadBalanceAndTransactions() {
refreshControl.beginRefreshing()
tableView.reloadWithAnimation()
//Reset
transactionPage = 0
callbackCount = 2
loadBalance()
loadMoreTransactions()
}
答案 0 :(得分:2)
很难做到这一点。要同步表格单元中的动画。
秘密在于,您需要一个信号系统-,它可以独立运行,并且独立于应用程序中的其他任何东西-并且可以跟踪时间。
该信号系统单例-每个单元都应连接到该单元并根据其进行动画处理。 (或者,根据您的风格,信号系统连接到单元并告诉他们该怎么做。)
享受!
答案 1 :(得分:1)
这就是我大致想出的。 VC控制单元何时使用动画功能。在动画的完成处理程序上,我们增加indexPath来动画下一个单元格。您将需要找到一种方法来防止用户向下滚动多个单元格。
要重置,只需将indexToAnimate设置为0并调用animateCells函数。
class ViewController: UIViewController {
var tableView: UITableView!
var indexRowToAnimate = 0
override func viewDidLoad() {
super.viewDidLoad()
addTableView()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
animateCells()
}
func addTableView() {
tableView = UITableView()
tableView.dataSource = self
tableView.register(UINib(nibName: String(describing: AnimatedCell.self), bundle: nil), forCellReuseIdentifier: String(describing: AnimatedCell.self))
view.addSubview(tableView)
tableView.pinTo(view: view)
}
func animateCells() {
guard let cell = tableView.cellForRow(at: IndexPath(row: indexRowToAnimate, section: 0)) as? AnimatedCell else { return }
tableView.bringSubviewToFront(cell)
cell.animateCell(tableFrame: tableView.frame) {
self.indexRowToAnimate += 1
self.animateCells()
}
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 100
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: AnimatedCell.self)) as? AnimatedCell else { return UITableViewCell() }
return cell
}
}
class AnimatedCell: UITableViewCell {
@IBOutlet var label: UILabel! // Label is pinned center x/y
override func awakeFromNib() {
super.awakeFromNib()
label.text = "Not animated yet"
isHidden = true
}
func animateCell(tableFrame: CGRect, completion: @escaping(() -> Void)) {
isHidden = false
let originalFrame = frame
UIView.animateKeyframes(withDuration: 1, delay: 0, options: .autoreverse, animations: {
self.frame = tableFrame
}) { (_) in
self.frame = originalFrame
self.label.text = "Animated"
completion()
}
}
}