2016-06-08 15 views
6

我有一个UIStackView 5个子视图。我希望能够通过更新intrinsicContentSize或更新其约束来动画这些子视图的宽度。如何在更新子视图的布局之后使堆栈查看重绘?如何获得UIStackView来更新其布局?

 UIView.animateWithDuration(0.3, animations: { 
      viewToResize.compressed = true //changes intrinsicContentSize 
      viewToResize.invalidateIntrinsicContentSize() 
      self.stackView.layoutIfNeeded() //makes no difference 
      anotherSubview.hidden = true //adding this makes everything work 
}) 

我试过各种方式试图让stackview更新,但没有任何反应。我能做到这一点的唯一方法是,如果我在动画块中显示/隐藏另一个子视图,那么新布局的动画是正确的,但我不想这样做。

我看到这个问题 Animating UIStackView arrangedSubview content size change 但建议的答案不起作用(没有动画)。

+0

你有没有尝试过view.updateConstraints? –

+0

是的,在堆栈视图和子视图上,都没有任何效果。 –

回答

6

您不需要viewToResize.invalidateIntrinsicContentSize(),而是更新您的子视图的约束。在下面的代码中,我们在stackView中有两个子视图,并且我们从故事板创建了一个widthConstraint插座。然后,我们可以通过更新动画块中的常量widthConstraint来动画子视图的宽度。 注:如果视图包含在堆栈视图中,并试图修改视图框,它不应该改变

class ViewController: UIViewController { 
    @IBOutlet var widthConstraint: NSLayoutConstraint! 

    @IBOutlet var stackView: UIStackView! 
    var compressed: Bool = true 

    @IBOutlet var start: UIButton! 

    @IBAction func onStart(sender: UIButton) { 
     UIView.animateWithDuration(3.0, 
            delay: 0.0, 
            usingSpringWithDamping: 0.3, 
            initialSpringVelocity: 10.0, 
            options: .CurveLinear, 
            animations: {() -> Void in 
            //self.stackView.invalidateIntrinsicContentSize() 
            self.widthConstraint.constant = (self.compressed == false) ? 100.0 : 200.0 
            self.compressed = !self.compressed 
            self.view.layoutIfNeeded() 
      }, completion: nil) 
    } 

有关详细信息,你可以看看这个伟大的博客UIStackView, Auto Layout and Core Animation

+0

如果我想要1个子视图具有固定宽度,而另一个填充可用空间,我该怎么做? (我想在视图之间切换)我尝试在动画块中删除/添加约束,它可以工作,但打破了其他约束。 –

+0

实际上,添加和删除约束效果很好,但我不得不降低优先级来阻止其他约束条件的破坏。 –

+0

我刚更新了链接。 – luiyezheng