更新:
我的问题:为什么?
原始问题(已更新以澄清)
我已收到某些应用的电池使用情况反馈。我使用xCode仪器来监控电池使用情况并发现问题。我静态地设置了UITableView / UICollectionView的backgroundView,它永远地调用了动画(让它称之为UICustomeActivityIndicator):
fileprivate func rotateLoadingView() {
UIView.animate(withDuration: 0.5, delay: 0.0, options: [.curveLinear], animations: {
self.innerCircleView.transform = self.innerCircleView.transform.rotated(by: CGFloat(M_PI_2))
}) { result in
if !self.isHidden {
self.rotateLoadingView()
}
}
}
然后,当内容被加载时,我通过将其设置为nil来清除backgroundView:
// collectionView.backgroundView = nil
tableView.backgroundView = nil
但是,即使我正在清除backgroundView,动画仍在继续,并且它正在使用巨大的电池(同时将应用程序发送到后台)。
我的问题;这种行为是正常的还是backgroundView UITableView / UICollectionView的错误,它应该在设置为nil时自动清除?
答案 0 :(得分:1)
您认为从层次结构中删除视图会导致系统取消动画,这是错误的。视图可能会添加到superview中,但无论如何都可以在其上运行动画,除非该对象已完全取消分配。因此,由于您在控制器中强烈引用了indicatorView
,因此它仍处于活动状态,并且没有理由删除您的动画。
我建议避免使用递归方法。您可以通过自定义活动指示器中的两种方法获得所需的结果:
func startAnimation() {
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateAnimation.fromValue = 0.0
rotateAnimation.toValue = CGFloat(M_PI * 2.0)
rotateAnimation.duration = 1
rotateAnimation.repeatCount = .infinity
layer.add(rotateAnimation, forKey: nil)
}
func stopRotation() {
layer.removeAllAnimations()
}
现在,只需在您的控制器中调用start
和stop
,您就不会遇到任何问题。
答案 1 :(得分:1)
删除视图不会删除动画,因为动画会添加到UIView图层中。将视图设置为nil不会更改图层属性。删除视图只会删除可见部分而不是图层属性。这就是动画在后台运行的原因。通过调用removeAllAnimations()
删除视图层中的所有动画view.layer.removeAllAnimations()