具有自动布局和子视图的UIView动画

时间:2017-09-20 08:40:12

标签: ios swift autolayout uiviewanimation

我有一个奇怪的问题似乎很容易解决。我想我可以使用一些解决方法来获得我想要的行为,但我想知道是否有更好的方法。

我有一个名为 contentView 的视图(图中的蓝色),它将使用UIView.animation扩展其高度,这完全没问题,并按预期工作。

这里的问题是这个视图有一个子组件(一个按钮),其底部的autolayout约束等于22,如下所示:

contentView with the button

这是自动布局约束:

enter image description here

如果我在没有动画的情况下调整高度大小它工作正常,视图高度更改和按钮始终是contentView底部的22个点。但是当我使用动画来使这个变化更加平滑和用户友好时,按钮会在动画开始之前移动到结束位置。

enter image description here

我想知道如何在这里实现平滑动画,但按钮沿着其父视图移动

处理动画的代码部分非常简单,但我会在这里发布:

@IBAction func openDetail(_ sender: ExpandCourseDetail) {
        let rotation = sender.getOpen() ? CGAffineTransform.identity : CGAffineTransform(rotationAngle: CGFloat.pi)
        UIView.animate(withDuration: 0.5, delay: 0.1, options: [.curveEaseInOut], animations: {
            sender.transform = rotation
        }, completion: {
            success in
            sender.setOpen(!sender.getOpen())
        })
        UIView.animate(withDuration: 1.0, delay: 0.5, options: [.curveEaseInOut], animations: {
            self.contentView.frame.size.height = sender.getOpen() ? self.contentView.frame.height - 300 : self.contentView.frame.height + 300
        }, completion: nil)
    }

作为旁注,按钮本身有一个动画,可以将按钮旋转180度,向用户显示视图正在扩展。

非常感谢你的帮助。

2 个答案:

答案 0 :(得分:2)

使用约束非常容易,只需创建一个superView高度约束IBOutlet并更改其常量值。

@IBAction func btnPressed(_ sender: UIButton) {
    self.toggleButton.isSelected = !sender.isSelected

    //Animation starts here
    self.view.layoutIfNeeded()
    UIView.animate(withDuration: 0.7) {

        if self.toggleButton.isSelected {
            //transform button
            self.toggleButton.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))

            //change your ParentView height to desired one
            self.constContentViewHeight.constant = self.view.frame.size.height - 220
            self.view.layoutIfNeeded()
        } else {

            self.toggleButton.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi*2))
            // Set height constraint to original value
            self.constContentViewHeight.constant = 250
            self.view.layoutIfNeeded()
        }
    }

}

我创建了一个演示,请查看。

demo

答案 1 :(得分:0)

您面临的问题是两个动画块。所以我改变了一些线条并将按钮变换和高度动画放到一个动画块中。

func openDetail(_ sender: ExpandCourseDetail) {

    let isOpen = sender.getOpen() ? CGAffineTransform.identity : CGAffineTransform(rotationAngle: CGFloat.pi)

    UIView.animate(withDuration: 1.0, delay: 0.5, options: [.curveEaseInOut], animations: {

        sender.transform = rotation
        self.contentView.frame.size.height = self.contentView.frame.height + (isOpen ? 300 : -300)

    }, completion: { (success) in
        sender.setOpen(!isOpen)
    })
}