我有一个UITextField,我想在点击时放大它的宽度。我设置了约束条件,并确保左边的约束条件优先级比右边的约束条件低。

这是我正在尝试使用的代码。

// move the input box
UIView.animateWithDuration(10.5, animations: {
    self.nameInputConstraint.constant = 8
    }, completion: {
        (value: Bool) in
        println(">>> move const")
})

这是有效的,但它似乎只是瞬间发生,似乎没有任何运动。我试着把它设置为10秒,以确保我没有错过任何东西,但我得到了同样的结果。

nameInputConstraint是约束的名称,我控制拖动连接到我的类从IB。


当前回答

非常重要的一点是,view. layoutifneeded()只应用于视图子视图。

因此,为了使视图约束动画化,在视图到动画的父视图上调用它是很重要的,如下所示:

    topConstraint.constant = heightShift

    UIView.animate(withDuration: 0.3) {

        // request layout on the *superview*
        self.view.superview?.layoutIfNeeded()
    }

一个简单布局的例子如下:

class MyClass {

    /// Container view
    let container = UIView()
        /// View attached to container
        let view = UIView()

    /// Top constraint to animate
    var topConstraint = NSLayoutConstraint()


    /// Create the UI hierarchy and constraints
    func createUI() {
        container.addSubview(view)

        // Create the top constraint
        topConstraint = view.topAnchor.constraint(equalTo: container.topAnchor, constant: 0)


        view.translatesAutoresizingMaskIntoConstraints = false

        // Activate constaint(s)
        NSLayoutConstraint.activate([
           topConstraint,
        ])
    }

    /// Update view constraint with animation
    func updateConstraint(heightShift: CGFloat) {
        topConstraint.constant = heightShift

        UIView.animate(withDuration: 0.3) {

            // request layout on the *superview*
            self.view.superview?.layoutIfNeeded()
        }
    }
}

其他回答

SWIFT 4及以上:

self.mConstraint.constant = 100.0
UIView.animate(withDuration: 0.3) {
        self.view.layoutIfNeeded()
}

补全示例:

self.mConstraint.constant = 100
UIView.animate(withDuration: 0.3, animations: {
        self.view.layoutIfNeeded()
    }, completion: {res in
        //Do something
})

您需要首先更改约束,然后对更新进行动画化。 这应该在父视图中。

self.nameInputConstraint.constant = 8

斯威夫特2

UIView.animateWithDuration(0.5) {
    self.view.layoutIfNeeded()
}

斯威夫特,3,4,5

UIView.animate(withDuration: 0.5) {
    self.view.layoutIfNeeded()
}

我想分享我的解决方案,在我不工作的情况下,我的约束设计如下

view1WidthLayout = NSLayoutConstraint(item: view1,
                                      attribute: .width,
                                      relatedBy: .equal,
                                      toItem: nil,
                                      attribute: .width,
                                      multiplier: 1,
                                      constant: 20)

当我试图在动画之前设置常数时

view1WidthLayout.constant += 20

它马上就凝固了,所以对我不起作用。

我改变了约束属性的定义

view1WidthLayout = view1.widthAnchor.constraint(equalToConstant: 20)

然后它对我有用

非常重要的一点是,view. layoutifneeded()只应用于视图子视图。

因此,为了使视图约束动画化,在视图到动画的父视图上调用它是很重要的,如下所示:

    topConstraint.constant = heightShift

    UIView.animate(withDuration: 0.3) {

        // request layout on the *superview*
        self.view.superview?.layoutIfNeeded()
    }

一个简单布局的例子如下:

class MyClass {

    /// Container view
    let container = UIView()
        /// View attached to container
        let view = UIView()

    /// Top constraint to animate
    var topConstraint = NSLayoutConstraint()


    /// Create the UI hierarchy and constraints
    func createUI() {
        container.addSubview(view)

        // Create the top constraint
        topConstraint = view.topAnchor.constraint(equalTo: container.topAnchor, constant: 0)


        view.translatesAutoresizingMaskIntoConstraints = false

        // Activate constaint(s)
        NSLayoutConstraint.activate([
           topConstraint,
        ])
    }

    /// Update view constraint with animation
    func updateConstraint(heightShift: CGFloat) {
        topConstraint.constant = heightShift

        UIView.animate(withDuration: 0.3) {

            // request layout on the *superview*
            self.view.superview?.layoutIfNeeded()
        }
    }
}

在我的例子中,我只更新了自定义视图。

// DO NOT LIKE THIS
customView.layoutIfNeeded()    // Change to view.layoutIfNeeded()
UIView.animate(withDuration: 0.5) {
   customViewConstraint.constant = 100.0
   customView.layoutIfNeeded() // Change to view.layoutIfNeeded()
}