7

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

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

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

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

4

2 回答 2

15

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

要解决它,您需要两件事:

  • 确保您正在编辑的约束与集合视图的位置有关,而不是大小。我的意思是你不是通过将它的高度从零更改为最终值来呈现你的集合视图。
  • 在编辑约束之前调用layoutIfNeeded您的视图,然后在进行更改后在动画块中再次调用它。这样,您只会对您指定给约束的更改进行动画处理,而不是对整个布局进行动画处理。
于 2013-06-26T21:28:54.877 回答
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}
}

看到魔法:)

于 2016-09-05T09:09:04.323 回答