UICollectionViewCell 中的 UIImageView 动画不起作用
UIImageView animation inside UICollectionViewCell doesn't work
我有一个 Collection View
有 5 个单元格(页)。
用户在打开 Collection View
时看到的第一页总是欢迎页面,下面有 UIImageView
和 2 个标签。
在 Collection View
控制器 did load
之后,我想向 UIImageView
添加一个简短的动画,以将其大小从原始大小增加 2。
我是这样尝试的:
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if indexPath.row == 0 {
guard let cell = collectionView.cellForItem(at: indexPath) as? WelcomeOnboardingCollectionViewCell else { return }
cell.animate()
}
}
动画方法如下:
class WelcomeOnboardingCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var subtitleLabel: UILabel!
func animate() {
UIView.animate(withDuration: 3, delay: 0, options: .curveEaseInOut) {
self.imageView.transform = CGAffineTransform(scaleX: 2, y: 2)
}
}
}
但是动画没有发生,我只看到最初的小 UIImageView
,尽管 print(cell)
正在工作,所以调用了该方法。
我也尝试在 cellForItemAt
中调用 cell.animate()
,但后来我看到已经增加了 UIImageView
而没有动画并且在 [=27= 中设置了哪个动画持续时间无关紧要]方法。
还尝试调用 scrollViewDidScroll
中的下一个代码,但没有成功:
collectionView.visibleCells.forEach { ([=12=] as? WelcomeOnboardingCollectionViewCell)?.animate() }
还尝试调用单元格 layoutIfNeeded()
,但它没有任何改变。
我错过了什么?
想要的结果:CLICK
Duncan 建议后的工作代码:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.item == 0 {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "WelcomeOnboardingCell", for: indexPath) as! WelcomeOnboardingCollectionViewCell
cell.imageView.image = UIImage(named: "\(slides[indexPath.row].imageName)")
cell.titleLabel.text = slides[indexPath.row].title
cell.subtitleLabel.text = slides[indexPath.row].subtitle
cell.animationPending = true
return cell
}
和 CollectionViewCell class:
class WelcomeOnboardingCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var subtitleLabel: UILabel!
var animationPending = false
override func didMoveToSuperview() {
if animationPending {
DispatchQueue.main.async {
self.animate()
}
}
animationPending = false
}
private func animate() {
UIView.animate(withDuration: 0.3, delay: 0.4, options: .curveEaseInOut) {
self.imageView.transform = CGAffineTransform(scaleX: 2.3, y: 2.3)
self.imageView.alpha = 1.0
}
}
}
选择:
在ViewController的viewDidAppear()
中调用animate()
:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
collectionView.visibleCells.forEach { ([=15=] as? WelcomeOnboardingCollectionViewCell)?.animate() }
}
在将单元格添加到视图层次结构之前,将调用 collectionView(_:willDisplay:forItemAt:)
方法和 collectionView(_:cellForItemAt:)
方法。在视图成为视图层次结构的一部分之前,您无法触发视图的动画。
我建议将动画“smarts”添加到您的 UICollectionViewCell
子类(或添加到您放在集合视图单元格中的内容视图。
让您的 collectionView(_:cellForItemAt:)
将您手机上的“animationPending”属性 设置为 true。
然后让您的 UICollectionViewCell
通过检查它的“animationPending”标志来响应 didMoveToSuperview()
调用。如果是,运行 你的动画代码并将标志设置回 false。
我有一个 Collection View
有 5 个单元格(页)。
用户在打开 Collection View
时看到的第一页总是欢迎页面,下面有 UIImageView
和 2 个标签。
在 Collection View
控制器 did load
之后,我想向 UIImageView
添加一个简短的动画,以将其大小从原始大小增加 2。
我是这样尝试的:
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if indexPath.row == 0 {
guard let cell = collectionView.cellForItem(at: indexPath) as? WelcomeOnboardingCollectionViewCell else { return }
cell.animate()
}
}
动画方法如下:
class WelcomeOnboardingCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var subtitleLabel: UILabel!
func animate() {
UIView.animate(withDuration: 3, delay: 0, options: .curveEaseInOut) {
self.imageView.transform = CGAffineTransform(scaleX: 2, y: 2)
}
}
}
但是动画没有发生,我只看到最初的小 UIImageView
,尽管 print(cell)
正在工作,所以调用了该方法。
我也尝试在 cellForItemAt
中调用 cell.animate()
,但后来我看到已经增加了 UIImageView
而没有动画并且在 [=27= 中设置了哪个动画持续时间无关紧要]方法。
还尝试调用 scrollViewDidScroll
中的下一个代码,但没有成功:
collectionView.visibleCells.forEach { ([=12=] as? WelcomeOnboardingCollectionViewCell)?.animate() }
还尝试调用单元格 layoutIfNeeded()
,但它没有任何改变。
我错过了什么?
想要的结果:CLICK
Duncan 建议后的工作代码:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.item == 0 {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "WelcomeOnboardingCell", for: indexPath) as! WelcomeOnboardingCollectionViewCell
cell.imageView.image = UIImage(named: "\(slides[indexPath.row].imageName)")
cell.titleLabel.text = slides[indexPath.row].title
cell.subtitleLabel.text = slides[indexPath.row].subtitle
cell.animationPending = true
return cell
}
和 CollectionViewCell class:
class WelcomeOnboardingCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var subtitleLabel: UILabel!
var animationPending = false
override func didMoveToSuperview() {
if animationPending {
DispatchQueue.main.async {
self.animate()
}
}
animationPending = false
}
private func animate() {
UIView.animate(withDuration: 0.3, delay: 0.4, options: .curveEaseInOut) {
self.imageView.transform = CGAffineTransform(scaleX: 2.3, y: 2.3)
self.imageView.alpha = 1.0
}
}
}
选择:
在ViewController的viewDidAppear()
中调用animate()
:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
collectionView.visibleCells.forEach { ([=15=] as? WelcomeOnboardingCollectionViewCell)?.animate() }
}
在将单元格添加到视图层次结构之前,将调用 collectionView(_:willDisplay:forItemAt:)
方法和 collectionView(_:cellForItemAt:)
方法。在视图成为视图层次结构的一部分之前,您无法触发视图的动画。
我建议将动画“smarts”添加到您的 UICollectionViewCell
子类(或添加到您放在集合视图单元格中的内容视图。
让您的 collectionView(_:cellForItemAt:)
将您手机上的“animationPending”属性 设置为 true。
然后让您的 UICollectionViewCell
通过检查它的“animationPending”标志来响应 didMoveToSuperview()
调用。如果是,运行 你的动画代码并将标志设置回 false。