对视觉对象格式语言约束进行动画处理



我正在尝试将按钮从容器的左侧动画化到右侧。此按钮的位置由视觉格式语言定义。(该项目是 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()
})

如果有人想知道,"addConstraintWithFormat"函数看起来像这样:

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的新手,因此我真的很感激一个有用的答案。

这是容器和更多按钮的图像。(都在最底部(

您的问题可能是您的约束未添加到正确的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的一些约束存储在moreButton的超级视图的constraints数组中。

将将来要停用的约束保留在 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
}

将属性添加到视图控制器:

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)

最新更新