动画视觉格式语言约束

时间:2018-08-24 13:42:15

标签: ios swift

我正在尝试从容器的左侧到右侧对按钮进行动画处理。此按钮的位置由可视格式语言定义。 (该项目为100%代码,不可能出现分镜脚本问题)

这些是我在左侧(有效)的线:

messageInputContainerView.addSubview(moreButton)
messageInputContainerView.addConstraintsWithFormat(format: "H:|-3-[v0(35)]-8-[v1][v2(60)]|", views: moreButton, ..., ...)
messageInputContainerView.addConstraintsWithFormat(format: "V:|[v0]|", views: moreButton)

这些用于右侧+动画(无效):

//I have read that I first have to remove the old constraints in order to apply new ones
moreButton.removeConstraints(moreButton.constraints)

//The only difference here is that the pipe ('|') is on the right side and that I don't care about the two other objects in the container
messageInputContainerView.addConstraintsWithFormat(format: "H:[v0(35)]-3-|", views: moreButton)
messageInputContainerView.addConstraintsWithFormat(format: "V:|[v0]|", views: moreButton)

...

//These lines should be fine, but I include them nontheless
UIView.animate(withDuration: 1, delay: 0, options: .curveEaseInOut, animations: {
      self.moreButton.setTitle("⤇", for: .normal)
      self.messageInputContainerView.layoutIfNeeded()
})

如果有人想知道,'addConstraintsWithFormat'函数如下所示:

extension UIView {

 func addConstraintsWithFormat(format: String, views: UIView...){

    var viewsDictionary = [String: UIView]()

    for (index, view) in views.enumerated(){
        let key = "v\(index)"
        viewsDictionary[key] = view
        view.translatesAutoresizingMaskIntoConstraints = false
    }

    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
  }

}

一般来说,我是VFL的新手,所以我非常感谢您提供有用的答案。

Here is an image of the container and the moreButton. (both at the very bottom)

1 个答案:

答案 0 :(得分:0)

您的问题可能是您的约束未添加到正确的UIView中。

如果您激活约束,而不必使用VFL约束调用NSLayoutConstraint(activate:),则不必担心会向视图添加约束:

extension UIView {

 func addConstraintsWithFormat(format: String, views: UIView...){

    var viewsDictionary = [String: UIView]()

    for (index, view) in views.enumerated(){
        let key = "v\(index)"
        viewsDictionary[key] = view
        view.translatesAutoresizingMaskIntoConstraints = false
    }

    NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
  }

}

然后有这行:

//I have read that I first have to remove the old constraints in order to apply new ones
moreButton.removeConstraints(moreButton.constraints)

同样,您应该停用约束(将其isActive属性设置为false),而不是删除约束。删除此类约束的问题在于,moreButton上的某些约束存储在constraints的超级视图的moreButton数组中。

保留将来要在VC中的数组中停用的约束,然后将约束传递给NSLayoutConstraint.deactivate()或将isActive属性设置为false以获得所需的约束停用。


更新

您的按钮动画不正确。那是因为它仍然与textField禁忌。要为moreButton制作动画,您需要使其摆脱约束其位置的其他约束。

首先,我将更改addConstraintsWithFormat(format:views:)以返回它作为[NSLayoutConstraint]创建的约束。这样一来,您以后就可以停用它们。

extension UIView {

 func addConstraintsWithFormat(format: String, views: UIView...) -> [NSLayoutConstraint] {

    var viewsDictionary = [String: UIView]()
    let constraints: [NSLayoutConstraint]

    for (index, view) in views.enumerated(){
        let key = "v\(index)"
        viewsDictionary[key] = view
        view.translatesAutoresizingMaskIntoConstraints = false
    }

    constraints = NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary)
    NSLayoutConstraint.activate(constraints)
    return constraints
}

向您的viewController添加属性:

var moreButtonConstraints = [NSLayoutConstraint]()

然后将格式"H:|-3-[v0(35)]-8-[v1][v2(60)]|"分解为"H:|-3-[v0(35)]""H:|-46-[v1][v2(60)]|"并分别激活它们。这样会将moreButton的约束与其他视图的约束分开,使您可以移动moreButton而不会影响其他视图。

messageInputContainerView.addSubview(moreButton)

// save these constraints in a property to be deactivated later
moreButtonConstraints = messageInputContainerView.addConstraintsWithFormat(format: "H:|-3-[v0(35)]", views: moreButton)

// we don't need to keep these constraints, so assign them to _
_ = messageInputContainerView.addConstraintsWithFormat(format: "H:|-46-[v1][v2(60)]|", views: ..., ...)
_ = messageInputContainerView.addConstraintsWithFormat(format: "V:|[v0]|", views: moreButton)

然后,当需要动画时:

// deactivate the old constraints
NSLayoutConstraint.deactivate(moreButtonConstraints)

// add constraints to move the moreButton to the right side
_ = messageInputContainerView.addConstraintsWithFormat(format: "H:[v0(35)]-3-|", views: moreButton)