在呈现UICollectionView时防止UICollectionViewCell动画外观

时间:2013-06-24 19:34:55

标签: ios uikit uicollectionview

当用户执行某些操作时,我需要从底部向上拉UICollectionView到一定高度。由于新状态完全是可选的,因此集合视图就在以这种方式呈现之前创建。从底部到顶部的动画是使用对NSLayoutConstraint的constant属性的更改以及在某个动画块中调用[view layoutIfNeeded]来执行的。

问题在于,以这种方式做事会使单元格以不受欢迎的方式出现:它们从左上角扩展到指定的大小。我希望集合视图能够出现,并且所有单元格都已经按照它们的最终尺寸和外观进行了布局。

我知道像UIView的setAnimationEnabled:方法之类的东西,但我似乎无法找到我应该如何以及在哪里使用它(如果这是要走的路)。

我猜问题是由于集合视图单元格在包含对[superview layoutIfNeeded]的调用的动画块之前被添加到视图层次结构中。这可能导致UIKit认为它还应该动画对布局的那些更改。如果是这种情况,那么解决方案可能就是从动画中排除,视图层次结构的特定更改。

2 个答案:

答案 0 :(得分:13)

从左上角展开通常是在原始视图从未布局时在动画块中调用layoutIfNeeded的症状。您基本上是为初始布局传递设置动画,其中所有子视图都是从CGRectZero开始的。

要解决这个问题,你需要做两件事:

  • 确保您正在编辑的约束与集合视图的位置相关,而不是大小。我的意思是,你不是通过将其高度从零改为最终值来呈现你的集合视图。
  • 在编辑约束之前在视图上调用layoutIfNeeded,然后在进行更改后再在动画块中再次调用约束。这样,您只需将您指定的更改设置为约束,而不是整个布局。

答案 1 :(得分:0)

我已经遇到这个问题大约3天了,终于得到了解决方案。 简单地说,我添加了一个非常小的计时器后调用的动画块

UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 7 , options: .CurveEaseInOut, animations: {
            self.view.layoutIfNeeded()
        }){ _ in}

将是

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
    dispatch_after(delayTime, dispatch_get_main_queue()) {
        self.changeConstraint()
    }

private func changeConstraint(){

        UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 7 , options: .CurveEaseInOut, animations: {
            self.view.layoutIfNeeded()
        }){ _ in}
}

看魔术:)