我创建了一个按钮,该按钮连接到顶部,开头和结尾并具有固定的高度。当我点击按钮时,新的UIView实例应与动画一起出现。
import UIKit
class ViewController: UIViewController {
var topButton = UIButton()
var myView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
topButton = UIButton(type: .roundedRect)
topButton.setTitle("Add Acctivity", for: .normal)
topButton.backgroundColor = UIColor.purple
topButton.setTitleColor(UIColor.white, for: .normal)
topButton.titleLabel?.font = UIFont(name: "System", size: 26)
topButton.translatesAutoresizingMaskIntoConstraints = false
topButton.addTarget(self, action: #selector(expandMenu), for: .touchUpInside)
view.addSubview(topButton)
topButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
topButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
topButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0).isActive = true
topButton.heightAnchor.constraint(equalToConstant: 70).isActive = true
myView.backgroundColor = UIColor.blue
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
myView.topAnchor.constraint(equalTo: view.topAnchor, constant: 70).isActive = true
myView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
myView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0).isActive = true
myView.heightAnchor.constraint(equalToConstant: 100).isActive = true
}
@objc func expandMenu() {
myView.heightAnchor.constraint(equalToConstant: 300).isActive = true
UIView.animate(withDuration: 1) {
self.view.layoutIfNeeded()
}
}
}
有趣的是,当我将高度设置为小于其初始值时,动画就会起作用。
当人们从情节提要中创建IBOutlet然后更改其恒定值时,我看到了许多教程。但是我想知道如何以编程方式做到这一点。
答案 0 :(得分:3)
您的代码中的问题是您试图重新激活另一个描述myView
高度的约束,方法是说(在expandMenu()
中):
myView.heightAnchor.constraint(equalToConstant: 300).isActive = true
我认为您会收到类似于以下内容的运行时警告:
[LayoutConstraints]无法同时满足约束。 以下列表中的约束中至少有一个是 你不要试试这个:(1)查看每个约束并尝试 找出你不期望的东西; (2)找到添加了 不必要的约束或约束并进行修复。 ( “ NSLayoutConstraint:0x60400008e5b0 UIView:0x7fa16a419450.height == 100(活动)>”, “ NSLayoutConstraint:0x608000097e30 UIView:0x7fa16a419450.height == 300(活动)>” )
将尝试通过打破约束来恢复
在UIViewAlertForUnsatisfiableConstraints处创建符号断点 在调试器中捕获它。中的方法 UIView中列出的UIConstraintBasedLayoutDebugging类别,在 可能也有帮助。
表示myView
已经有一个高度限制,即(在viewDidLoad()
中):
myView.heightAnchor.constraint(equalToConstant: 100).isActive = true
您应该做的是改为更改同一约束的constant
值。您可以这样实现:
将NSLayoutConstraint
声明为实例变量:
var myViewHeightConstraint: NSLayoutConstraint!
和viewDidLoad()
中的
myViewHeightConstraint = NSLayoutConstraint(item: myView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: 100)
myViewHeightConstraint.isActive = true
代替:
myView.heightAnchor.constraint(equalToConstant: 100).isActive = true
最后,在expandMenu()
中:
myViewHeightConstraint.constant = 300
代替:
myView.heightAnchor.constraint(equalToConstant: 300).isActive = true
输出:
此外:
如果您要让同一按钮实现展开/折叠行为,则只需将其实现为(在expandMenu()
中):
myViewHeightConstraint.constant = myViewHeightConstraint.constant == 300 ? 100 : 300
答案 1 :(得分:1)
constraint
方法返回一个NSLayoutConstraint
。您可以将其分配给类级变量:
var heightConstraint: NSLayoutConstraint!
override func viewDidLoad() {
// ...
heightConstraint = myView.heightAnchor.constraint(equalToConstant: 100)
heightConstraint.isActive = true
}
然后您将拥有一个属性heightConstraint
,它非常类似于IBOutlet
。您可以像对IBOutlet
约束进行动画处理一样对它进行动画处理。