为什么我的动画不流畅?
Why my animation is not smooth?
当我将左约束从 0 更改为 (self.bounds.width - self.bounds.width/3) 时,我正在尝试使用自定义 class 为文本字段设置动画动画不流畅,但是当我将它设置回 0 时,效果很好。
这是我的部分习惯class:
lazy var leftConstraint = NSLayoutConstraint(item: placeholderLabel, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1, constant: 0)
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.delegate = self
self.addSubview(placeholderLabel)
self.bringSubview(toFront: self)
addConstraints()
}
func addConstraints() {
placeholderLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: placeholderLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: self.bounds.height).isActive = true
self.leftConstraint.isActive = true
NSLayoutConstraint(item: placeholderLabel, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: placeholderLabel, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 0).isActive = true
}
func textFieldDidBeginEditing(_ textField: UITextField) {
animate(constant: self.bounds.width - self.bounds.width/3)
self.bringSubview(toFront: placeholderLabel)
}
func textFieldDidEndEditing(_ textField: UITextField) {
if (textField.text?.isEmpty)!{
animate(constant: 0)
self.bringSubview(toFront: self)
}
}
func animate(constant: CGFloat) {
self.leftConstraint.constant = constant
UIView.animate(withDuration: 0.15) {
self.layoutIfNeeded()
}
}
尝试使用 CGAffineTransform
而不是动画约束。它可以实现任意变换之王(平移、旋转、缩放)。
加上 animate 函数的选项,你几乎可以实现任何东西
翻译动画示例:
UIView.animate(withDuration: 0.7, delay: 0,
usingSpringWithDamping: 1, initialSpringVelocity: 0,
options: .curveEaseOut, animations:
{
self.anyElement.transform = CGAffineTransform(
translationX: 0,
y: 100)
}, completion:
{ (success) in
self.anyElement.transform = .identity
})
动画不流畅的可能原因
func animate(constant: CGFloat) {
/// Modifying Constraint out of animation
/// This will animate in micro seconds and you wont get a
/// Smooth Animation
self.leftConstraint.constant = constant
/// Take this Line (Cut)
UIView.animate(withDuration: 2) {
/// Animation will take time to Happen
self.leftConstraint.constant = constant
/// Need to call this inside animation block
self.view.layoutIfNeeded()
}
}
试过代码
import UIKit
class ViewController: UIViewController
{
private var customView : UIView?
private var leftConstraint : NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
customView = UIView()
customView?.backgroundColor = .red
leftConstraint = NSLayoutConstraint()
addConstraints()
DispatchQueue.main.async {
self.animateView()
}
}
func addConstraints(){
self.view.addSubview(customView!)
customView?.translatesAutoresizingMaskIntoConstraints = false
leftConstraint = customView?.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 50)
leftConstraint?.isActive = true
customView?.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -50).isActive = true
customView?.heightAnchor.constraint(equalToConstant: 50).isActive = true
customView?.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50).isActive = true
}
func animateView(){
UIView.animate(withDuration: 2) {
/// Animation will take time to Happen
self.leftConstraint?.constant = 100
/// Need to call this inside animation block
self.view.layoutIfNeeded()
}
}
}
输出
当我将左约束从 0 更改为 (self.bounds.width - self.bounds.width/3) 时,我正在尝试使用自定义 class 为文本字段设置动画动画不流畅,但是当我将它设置回 0 时,效果很好。
这是我的部分习惯class:
lazy var leftConstraint = NSLayoutConstraint(item: placeholderLabel, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1, constant: 0)
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.delegate = self
self.addSubview(placeholderLabel)
self.bringSubview(toFront: self)
addConstraints()
}
func addConstraints() {
placeholderLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: placeholderLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: self.bounds.height).isActive = true
self.leftConstraint.isActive = true
NSLayoutConstraint(item: placeholderLabel, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: placeholderLabel, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 0).isActive = true
}
func textFieldDidBeginEditing(_ textField: UITextField) {
animate(constant: self.bounds.width - self.bounds.width/3)
self.bringSubview(toFront: placeholderLabel)
}
func textFieldDidEndEditing(_ textField: UITextField) {
if (textField.text?.isEmpty)!{
animate(constant: 0)
self.bringSubview(toFront: self)
}
}
func animate(constant: CGFloat) {
self.leftConstraint.constant = constant
UIView.animate(withDuration: 0.15) {
self.layoutIfNeeded()
}
}
尝试使用 CGAffineTransform
而不是动画约束。它可以实现任意变换之王(平移、旋转、缩放)。
加上 animate 函数的选项,你几乎可以实现任何东西
翻译动画示例:
UIView.animate(withDuration: 0.7, delay: 0,
usingSpringWithDamping: 1, initialSpringVelocity: 0,
options: .curveEaseOut, animations:
{
self.anyElement.transform = CGAffineTransform(
translationX: 0,
y: 100)
}, completion:
{ (success) in
self.anyElement.transform = .identity
})
动画不流畅的可能原因
func animate(constant: CGFloat) {
/// Modifying Constraint out of animation
/// This will animate in micro seconds and you wont get a
/// Smooth Animation
self.leftConstraint.constant = constant
/// Take this Line (Cut)
UIView.animate(withDuration: 2) {
/// Animation will take time to Happen
self.leftConstraint.constant = constant
/// Need to call this inside animation block
self.view.layoutIfNeeded()
}
}
试过代码
import UIKit
class ViewController: UIViewController
{
private var customView : UIView?
private var leftConstraint : NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
customView = UIView()
customView?.backgroundColor = .red
leftConstraint = NSLayoutConstraint()
addConstraints()
DispatchQueue.main.async {
self.animateView()
}
}
func addConstraints(){
self.view.addSubview(customView!)
customView?.translatesAutoresizingMaskIntoConstraints = false
leftConstraint = customView?.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 50)
leftConstraint?.isActive = true
customView?.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -50).isActive = true
customView?.heightAnchor.constraint(equalToConstant: 50).isActive = true
customView?.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50).isActive = true
}
func animateView(){
UIView.animate(withDuration: 2) {
/// Animation will take time to Happen
self.leftConstraint?.constant = 100
/// Need to call this inside animation block
self.view.layoutIfNeeded()
}
}
}
输出