如何使用约束从下到上为 UIView 设置动画?
How to animate UIView using constraint from bottom to top?
我正在以编程方式创建 UIView,然后我将使用约束从下到上为该视图设置动画。但是这个视图对象上没有显示动画。
overlay!.addSubview(contentView)
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.leadingAnchor.constraint(equalTo: vc.view.leadingAnchor, constant: 20).isActive = true
contentView.trailingAnchor.constraint(equalTo: vc.view.trailingAnchor, constant: -20).isActive = true
contentView.addSubview(messageLabel)
messageLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8).isActive = true
messageLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8).isActive = true
messageLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8).isActive = true
messageLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8).isActive = true
let width: CGFloat = vc.view.frame.width - 40 - 16
stringHeight = calculateEstimatedHeight(width: width, text: text) + 16
contentView.heightAnchor.constraint(equalToConstant: stringHeight).isActive = true
bottomConstraint = contentView.bottomAnchor.constraint(equalTo: vc.view.bottomAnchor, constant: stringHeight)
bottomConstraint.isActive = true
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
self.showToastViewWithAnimation(viewController: vc)
}
@objc func showToastViewWithAnimation(viewController: Any) {
if let vc = viewController as? ViewController {
vc.view.layoutIfNeeded()
UIView.animate(withDuration: 0.8) {
self.bottomConstraint.constant = -20
vc.view.layoutIfNeeded()
}
}
}
我已经通过评论指出了一些事情,阅读评论你会明白你的代码中的问题是什么,检查下面的代码。
=> 你的代码:overlay!.addSubview(contentView)
@objc func showToastViewWithAnimation(viewController: Any) {
if let vc = viewController as? ViewController {
//vc.view.layoutIfNeeded() - this is not required before updating constraint value
self.bottomConstraint.constant = -20 //update contstraint outside of the animation block
UIView.animate(withDuration: 0.8) {
//vc.view.layoutIfNeeded()
self.overlay?.layoutIfNeeded() //you needs to layout the overlay view, as your other toast views are added in overlay view and not in view of viewcontroller as per your code
}
}
}
在您的代码中添加这一行:
self.translatesAutoresizingMaskIntoConstraints = false
contentView.translatesAutoresizingMaskIntoConstraints = false
然后在你的 ShowToastView 函数中首先找到哪个是底部约束,然后尝试像这样更新它(记住它的提示代码,你可以根据你的要求更新它):
@objc func showToastViewWithAnimation(viewController: Any) {
if let vc = viewController as? ViewController {
if let bottom = self.contentView.superview?.constraints.first(where: { (constraint) -> Bool in
return constraint.firstAttribute == .bottom}){
// in this condition find your bottom constraint and update it, don't save your constraint in a variable.
bottom.constant = -20
UIView.animate(withDuration: 0.8, animations: {
vc.view.layoutIfNeeded()
}) { (complete) in
}
}
}
}
我正在以编程方式创建 UIView,然后我将使用约束从下到上为该视图设置动画。但是这个视图对象上没有显示动画。
overlay!.addSubview(contentView)
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.leadingAnchor.constraint(equalTo: vc.view.leadingAnchor, constant: 20).isActive = true
contentView.trailingAnchor.constraint(equalTo: vc.view.trailingAnchor, constant: -20).isActive = true
contentView.addSubview(messageLabel)
messageLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8).isActive = true
messageLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8).isActive = true
messageLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8).isActive = true
messageLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8).isActive = true
let width: CGFloat = vc.view.frame.width - 40 - 16
stringHeight = calculateEstimatedHeight(width: width, text: text) + 16
contentView.heightAnchor.constraint(equalToConstant: stringHeight).isActive = true
bottomConstraint = contentView.bottomAnchor.constraint(equalTo: vc.view.bottomAnchor, constant: stringHeight)
bottomConstraint.isActive = true
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
self.showToastViewWithAnimation(viewController: vc)
}
@objc func showToastViewWithAnimation(viewController: Any) {
if let vc = viewController as? ViewController {
vc.view.layoutIfNeeded()
UIView.animate(withDuration: 0.8) {
self.bottomConstraint.constant = -20
vc.view.layoutIfNeeded()
}
}
}
我已经通过评论指出了一些事情,阅读评论你会明白你的代码中的问题是什么,检查下面的代码。
=> 你的代码:overlay!.addSubview(contentView)
@objc func showToastViewWithAnimation(viewController: Any) {
if let vc = viewController as? ViewController {
//vc.view.layoutIfNeeded() - this is not required before updating constraint value
self.bottomConstraint.constant = -20 //update contstraint outside of the animation block
UIView.animate(withDuration: 0.8) {
//vc.view.layoutIfNeeded()
self.overlay?.layoutIfNeeded() //you needs to layout the overlay view, as your other toast views are added in overlay view and not in view of viewcontroller as per your code
}
}
}
在您的代码中添加这一行:
self.translatesAutoresizingMaskIntoConstraints = false
contentView.translatesAutoresizingMaskIntoConstraints = false
然后在你的 ShowToastView 函数中首先找到哪个是底部约束,然后尝试像这样更新它(记住它的提示代码,你可以根据你的要求更新它):
@objc func showToastViewWithAnimation(viewController: Any) {
if let vc = viewController as? ViewController {
if let bottom = self.contentView.superview?.constraints.first(where: { (constraint) -> Bool in
return constraint.firstAttribute == .bottom}){
// in this condition find your bottom constraint and update it, don't save your constraint in a variable.
bottom.constant = -20
UIView.animate(withDuration: 0.8, animations: {
vc.view.layoutIfNeeded()
}) { (complete) in
}
}
}
}