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

Ios 带有自动布局和子视图的UIView动画,ios,swift,autolayout,uiviewanimation,Ios,Swift,Autolayout,Uiviewanimation,我有一个奇怪的问题,似乎很容易解决。我想我可以使用一些变通方法来实现我想要的行为,但我想知道是否有更好的方法来做到这一点 我有一个名为contentView(图中为蓝色)的视图,它将使用UIView.animation扩展其高度,这一点都没有问题,并按预期工作 这里的问题是,此视图有一个子组件(按钮),其底部的autolayout约束等于22,如下所示: 这是自动布局约束: 如果我在没有动画的情况下调整高度,效果会很好,视图高度会发生变化,按钮始终位于contentView底部的22个点。但

我有一个奇怪的问题,似乎很容易解决。我想我可以使用一些变通方法来实现我想要的行为,但我想知道是否有更好的方法来做到这一点

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

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

这是自动布局约束:

如果我在没有动画的情况下调整高度,效果会很好,视图高度会发生变化,按钮始终位于contentView底部的22个点。但是,当我使用动画使此更改更加平滑和用户友好时,按钮会在动画开始之前移动到结束位置

我想知道如何在按钮沿其父视图移动的情况下实现平滑动画

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

@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度的动画,以向用户显示视图正在扩展


非常感谢您的帮助。

使用约束非常简单,只需创建superView高度约束并更改其常量值即可

@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()
        }
    }

}
我已经创建了一个演示,请查看


使用约束非常简单,只需创建superView高度约束并更改其常量值即可

@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()
        }
    }

}
我已经创建了一个演示,请查看


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

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

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

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

您可以尝试通过更改heightConstraint.constant而不是设置帧大小来更改contentView的高度。但我不确定它是否会起作用。(需要先设置约束,然后再设置动画WithDuration,然后调用动画块中需要的view.LayoutIfNeed)不要更改contentView帧,如果使用autolayout,该帧将无效。设置高度约束并尝试调整常量值,调用self.view.layoutIfNeeded()并将按钮固定到该contentvView底部您可以通过更改heightConstraint.constant而不是设置帧大小来尝试更改contentView的高度。但我不确定它是否会起作用。(需要先设置约束,然后再设置动画WithDuration,然后调用动画块中需要的view.LayoutIfNeed)不要更改contentView帧,如果使用autolayout,该帧将无效。设置高度约束并尝试调整常量值,调用self.view.layoutIfNeeded()并将按钮固定到contentvView底部