ios - 动画视觉格式语言约束
问题描述
我正在尝试为从容器左侧到右侧的按钮设置动画。此按钮的位置由视觉格式语言定义。(该项目是 100% 代码,没有 Storyboard 问题可能)
这些是我左侧的线条(工作):
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 的新手,因此我非常感谢一个有用的答案。
解决方案
您的问题很可能是您的约束没有添加到正确UIView
的 s.
NSLayoutConstraint(activate:)
如果您通过调用VFL 约束来激活约束,则不必担心向视图添加约束:
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)
推荐阅读
- mongodb - 有没有办法限制MongoDB中的用户资源?
- python - Django 过滤器模块:查找表达式(年份)未返回所需的查询集
- sql - Rails 和 SQL - 与数组、条目中的所有元素相关联
- python - python 套接字中的 TCP 问题,会产生发送多个图像的问题
- java - 在我没有回复消息之前,我们如何才能在 Java rabbitmq 的队列中接收不到新消息?
- javascript - 水平滚动上的粘性表格标题
- coq - 在逻辑基础中证明 MStar' (IndProp.v)
- amazon-web-services - 无法将服务角色策略附加到客户角色
- php - 如何在 Laravel API 中使用电话号码和 OTP 而不是密码对用户进行身份验证?
- azure-pipelines - 在 API 响应中设置日落标头