尝试在collectionview中为不可见单元格设置动画时如何防止延迟
Posted
技术标签:
【中文标题】尝试在collectionview中为不可见单元格设置动画时如何防止延迟【英文标题】:how to prevent delay when trying to animate invisible cells in collectionview 【发布时间】:2020-12-30 21:55:36 【问题描述】:我想为我的所有 collectionview 单元格设置动画,这个简化的示例说明了这个问题。问题是,如果我在动画单元格时向下滚动,那么不可见的单元格会延迟动画。我希望不可见的单元格处于动画的最终状态,而不是动画延迟。
在视频中你看到,当我滚动到底部时,最后的单元格开始延迟动画。
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
var collectionview: UICollectionView!
var moveText: Bool = false
override func viewDidLoad()
super.viewDidLoad()
collectionview = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
collectionview.translatesAutoresizingMaskIntoConstraints = false
collectionview.dataSource = self
collectionview.delegate = self
collectionview.backgroundColor = .systemBackground
collectionview.register(MyCell.self, forCellWithReuseIdentifier: "cell")
view.addSubview(collectionview)
NSLayoutConstraint.activate([
collectionview.topAnchor.constraint(equalTo: view.topAnchor),
collectionview.bottomAnchor.constraint(equalTo: view.bottomAnchor),
collectionview.leadingAnchor.constraint(equalTo: view.leadingAnchor),
collectionview.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
10
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionview.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyCell
UIView.animate(withDuration: 1, delay: 0, options: [
UIView.AnimationOptions.allowAnimatedContent,
UIView.AnimationOptions.allowUserInteraction,
])
cell.moveText = self.moveText
return cell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
return .init(width: collectionview.frame.width, height: 120)
override func viewDidAppear(_ animated: Bool)
super.viewDidAppear(animated)
Timer.scheduledTimer(withTimeInterval: 1.5, repeats: true) timer in
print("Starting animatings")
self.moveText.toggle()
self.collectionview.reloadData()
class MyCell: UICollectionViewCell
let label = UILabel()
var moveText: Bool = false
didSet
if moveText == true
label.transform = CGAffineTransform(translationX: 50, y: 50)
else
label.transform = .identity
override init(frame: CGRect)
super.init(frame: frame)
label.text = "mytext"
label.translatesAutoresizingMaskIntoConstraints = false
addSubview(label)
NSLayoutConstraint.activate([
label.leadingAnchor.constraint(equalTo: leadingAnchor),
label.topAnchor.constraint(equalTo: topAnchor)
])
backgroundColor = .orange
required init?(coder: NSCoder)
fatalError("init(coder:) has not been implemented")
【问题讨论】:
【参考方案1】:而不是在cellForItemAt
中添加这个辅助函数。
private func animateVisibleCells()
collectionview.visibleCells.compactMap $0 as? MyCell .forEach cell in
UIView.animate(withDuration: 1, delay: 0, options: [
UIView.AnimationOptions.allowAnimatedContent,
UIView.AnimationOptions.allowUserInteraction,
])
cell.moveText = self.moveText
现在调用它而不是重新加载集合视图
Timer.scheduledTimer(withTimeInterval: 1.5, repeats: true) timer in
print("Starting animatings")
self.moveText.toggle()
self.animateVisibleCells()
并将cellForItemAt
实现转换为:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionview.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyCell
cell.moveText = moveText
return cell
【讨论】:
感谢您的回答。我明白了,但由于某种原因它不起作用,如果你在动画不可见单元格处于旧位置时快速滚动以上是关于尝试在collectionview中为不可见单元格设置动画时如何防止延迟的主要内容,如果未能解决你的问题,请参考以下文章