在UITableView

时间:2016-10-26 11:12:01

标签: ios swift uitableview uicollectionview uiviewanimation

更新:

  1. 我有一个UITableView,可以从Web服务加载数据。
  2. 在加载数据时,我将其backgroundView设置为UIAnyCustomView(UIView的子类),我以编程方式绘制并为其设置动画。
  3. 从网络服务收到数据后,我将UITableView的backgroundView设置为nil,因为它是可选的,我认为动画应该自动删除,但它们不是。
  4. 我的问题:为什么?

    原始问题(已更新以澄清)

    我已收到某些应用的电池使用情况反馈。我使用xCode仪器来监控电池使用情况并发现问题。我静态地设置了UITableView / UICollectionView的backgroundView,它永远地调用了动画(让它称之为UICustomeActivityIndi​​cator):

    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时自动清除?

2 个答案:

答案 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()
}

现在,只需在您的控制器中调用startstop,您就不会遇到任何问题。

答案 1 :(得分:1)

删除视图不会删除动画,因为动画会添加到UIView图层中。将视图设置为nil不会更改图层属性。删除视图只会删除可见部分而不是图层属性。这就是动画在后台运行的原因。通过调用removeAllAnimations()

删除视图层中的所有动画
view.layer.removeAllAnimations()