呈现UICollectionView时防止UICollectionViewCellanimation外观

当用户做了一些动作,我需要从底部拉起一个UICollectionView到一定的高度。 由于这个新状态是完全可选的,因此集合视图就在这样呈现之前被创build。 从底部到顶部的animation是通过改变NSLayoutConstraint的constant属性和在一些animation块中调用[view layoutIfNeeded]来实现的。

问题在于,这样做会使单元格以不希望的方式出现:从左上angular扩展到指定的大小。 我希望集合视图能够出现,并且所有的单元格都已经按照最终的大小和外观进行布置。

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

我猜这个问题是由于集合视图单元格被添加到包含对[superview layoutIfNeeded]的调用的animation块之前的视图层次结构中。 这可能会导致UIKit认为它也应该dynamic改变布局。 如果是这种情况,解决scheme可能是沿着从animation中排除的方式,视图层次结构的特定改变。

从左上angular扩展通常是在原始视图从未布置过的情况下调用layoutIfNeeded一个症状。 你基本上是animation的初始布局通过,所有的子视图已经开始在CGRectZero。

要解决它,你需要两件事情:

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

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

 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} } 

看魔术:)