以编程方式动画约束Swift 3

时间:2017-07-30 22:32:38

标签: swift animation

我有一个视图,我通过约束设置了位置和大小:

    oV.centerXAnchor.constraint(equalTo: self.mapViewController.view.centerXAnchor).isActive = true
    oV.centerYAnchor.constraint(equalTo: self.mapViewController.view.centerYAnchor).isActive = true
    oV.widthAnchor.constraint(equalTo: self.mapViewController.view.widthAnchor, constant: -overlaySpacing).isActive = true
    oV.heightAnchor.constraint(equalTo: self.mapViewController.view.heightAnchor, constant: -overlaySpacing).isActive = true

但是,我希望oV(视图)开始时小于此值,并在一秒钟内设置最终大小的动画。

oV.centerXAnchor.constraint(equalTo: self.mapViewController.view.centerXAnchor).isActive = true
oV.centerYAnchor.constraint(equalTo: self.mapViewController.view.centerYAnchor).isActive = true
oV.widthAnchor.constraint(equalTo: self.mapViewController.view.widthAnchor, constant: -2 * overlaySpacing).isActive = true
oV.heightAnchor.constraint(equalTo: self.mapViewController.view.heightAnchor, constant: -2 * overlaySpacing).isActive = true

我写的初始约束是常量为(-2 * overlaySpacing)的约束。最后的约束是宽度/高度常量只是-overlaySpacing。

我已经以编程方式编写了所有内容,因此故事板解决方案无济于事。

这是我当前的动画代码,但它只是自动显示为最终约束:

让oV = NewOverlayView(viewController:mVC,frame:CGRect.zero)

    self.mapViewController.view.addSubview(oV)

    oV.centerXAnchor.constraint(equalTo: self.mapViewController.view.centerXAnchor).isActive = true
    oV.centerYAnchor.constraint(equalTo: self.mapViewController.view.centerYAnchor).isActive = true
    var widthConstraint = oV.widthAnchor.constraint(equalTo: self.mapViewController.view.widthAnchor, constant: -2 * overlaySpacing)
    var heightConstraint = oV.heightAnchor.constraint(equalTo: self.mapViewController.view.heightAnchor, constant: -2 * overlaySpacing)

    widthConstraint.isActive = true
    heightConstraint.isActive = true

    oV.layoutIfNeeded()

    widthConstraint.isActive = false
    heightConstraint.isActive = false

    widthConstraint = oV.widthAnchor.constraint(equalTo: self.mapViewController.view.widthAnchor, constant: -overlaySpacing)
    heightConstraint = oV.heightAnchor.constraint(equalTo: self.mapViewController.view.heightAnchor, constant: -overlaySpacing)

    widthConstraint.isActive = true
    heightConstraint.isActive = true

    UIView.animate(withDuration: 1.0) { oV.layoutIfNeeded() }

谢谢!

1 个答案:

答案 0 :(得分:1)

具有proper function动画的属性观察者可以是一个解决方案:
 

1。

使用“didSet”观察器在控制器中设置变量,如下所示:

    var dynamicOverlaySpacing = 0 {
    didSet {
             //Remove previous constraints ?        
             oV.widthAnchor.constraint(equalTo: self.mapViewController.view.widthAnchor, constant: -dynamicOverlaySpacing).isActive = true
             oV.heightAnchor.constraint(equalTo: self.mapViewController.view.heightAnchor, constant: -dynamicOverlaySpacing).isActive = true
        }
    }


永远改变 dynamicOverlaySpacing 的值,将执行didSet闭包中的代码。
 

2。

制作动画,慢慢改变 dynamicOverlaySpacing的值

这样的事情应该有效:

let delay = 2.0 //the delay you want for the animation
let firstOverlaySpacing = dynamicOverlaySpacing
oV.animate(withDuration: 0, delay: delay, options: .curveEaseIn, animations: {
             dynamicOverlaySpacing = -2*firstOverlaySpacing

            }, completion: nil)

在选项上,我使用curseEaseIn。您可以看到所有可用选项here.

我没有尝试代码,但它应该可以工作。