2013-06-24 29 views
6

当用户执行某些操作时,我需要从底部拉起UICollectionView直到某个高度。由于该新状态是完全可选的,所以在以这种方式呈现之前创建集合视图。从底部到顶部的动画是使用NSLayoutConstraint的constant属性更改以及在某些动画块中调用[view layoutIfNeeded]执行的。当呈现UICollectionView时防止UICollectionViewCell动画外观

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

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

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

+0

运行到我的应用程序一些类似的错误 - 对例如,当我在模拟器中启动它时,整个应用程序的屏幕从左上角向外扩展,某些文本片段有时会跳转到其超级视图的左角,然后生成向下的动画。同样,我在我的应用程序的不同部分制作了几个带有约束的动画。希望能回答这个问题:) –

回答

10

从左上角扩展通常是在原始视图从未布置过的情况下,在动画块中调用layoutIfNeeded的症状。你基本上是在CGRectZero中开始所有子视图的初始布局过程的动画。

为了解决它,你需要两样东西:

  • 确保您正在编辑有关集合视图,而不是大小的位置约束。通过这个,我的意思是说你不会通过改变其高度从零到最终值来呈现你的集合视图。
  • 在编辑约束之前在您的视图上调用layoutIfNeeded,然后在进行更改后再在动画块中再次调用它。通过这种方式,您只会将您为约束指定的更改动态化,而不是整个布局。
+1

它的工作!非常感谢!作为参考,我所做的是创建一个低优先级约束,使集合视图高度等于窗口高度,调用'layoutIfNeeded',设置更高优先级的约束来覆盖前一个约束,并执行动画!它运作得非常好! – matehat

+0

我只能在22小时内奖励赏金...... – matehat

+0

利用优先权是一个好主意!我即将写出类似的东西,我通常会引用各种约束,但这次我会尝试一下。 – jrturton

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

见神奇:)