使用 Swift 5 和 iOS 12.3,根据您的需要,您可以选择以下 3 种方式之一来解决您的问题。
#1。使用UIView的animate(withDuration:animations:)类方法
animate(withDuration:animations:) 具有以下声明:
使用指定的持续时间对一个或多个视图进行动画更改。
class func animate(withDuration duration: TimeInterval, animations: @escaping () -> Void)
下面的 Playground 代码显示了animate(withDuration:animations:) 的可能实现,以便为自动布局约束的不断变化设置动画。
import UIKit
import PlaygroundSupport
class ViewController: UIViewController {
let textView = UITextView()
lazy var heightConstraint = textView.heightAnchor.constraint(equalToConstant: 50)
override func viewDidLoad() {
view.backgroundColor = .white
view.addSubview(textView)
textView.backgroundColor = .orange
textView.isEditable = false
textView.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
textView.translatesAutoresizingMaskIntoConstraints = false
textView.topAnchor.constraint(equalToSystemSpacingBelow: view.layoutMarginsGuide.topAnchor, multiplier: 1).isActive = true
textView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor).isActive = true
textView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor).isActive = true
heightConstraint.isActive = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(doIt(_:)))
textView.addGestureRecognizer(tapGesture)
}
@objc func doIt(_ sender: UITapGestureRecognizer) {
heightConstraint.constant = heightConstraint.constant == 50 ? 150 : 50
UIView.animate(withDuration: 2) {
self.view.layoutIfNeeded()
}
}
}
PlaygroundPage.current.liveView = ViewController()
#2。使用UIViewPropertyAnimator的init(duration:curve:animations:)初始化器和startAnimation()方法
init(duration:curve:animations:) 有以下声明:
使用内置的 UIKit 时序曲线初始化动画器。
convenience init(duration: TimeInterval, curve: UIViewAnimationCurve, animations: (() -> Void)? = nil)
下面的 Playground 代码显示了 init(duration:curve:animations:) 和 startAnimation() 的可能实现,以便为自动布局约束的不断变化设置动画。
import UIKit
import PlaygroundSupport
class ViewController: UIViewController {
let textView = UITextView()
lazy var heightConstraint = textView.heightAnchor.constraint(equalToConstant: 50)
override func viewDidLoad() {
view.backgroundColor = .white
view.addSubview(textView)
textView.backgroundColor = .orange
textView.isEditable = false
textView.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
textView.translatesAutoresizingMaskIntoConstraints = false
textView.topAnchor.constraint(equalToSystemSpacingBelow: view.layoutMarginsGuide.topAnchor, multiplier: 1).isActive = true
textView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor).isActive = true
textView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor).isActive = true
heightConstraint.isActive = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(doIt(_:)))
textView.addGestureRecognizer(tapGesture)
}
@objc func doIt(_ sender: UITapGestureRecognizer) {
heightConstraint.constant = heightConstraint.constant == 50 ? 150 : 50
let animator = UIViewPropertyAnimator(duration: 2, curve: .linear, animations: {
self.view.layoutIfNeeded()
})
animator.startAnimation()
}
}
PlaygroundPage.current.liveView = ViewController()
#3。使用UIViewPropertyAnimator的runningPropertyAnimator(withDuration:delay:options:animations:completion:)类方法
runningPropertyAnimator(withDuration:delay:options:animations:completion:) 具有以下声明:
创建并返回一个动画对象,该对象立即开始运行其动画。
class func runningPropertyAnimator(withDuration duration: TimeInterval, delay: TimeInterval, options: UIViewAnimationOptions = [], animations: @escaping () -> Void, completion: ((UIViewAnimatingPosition) -> Void)? = nil) -> Self
下面的 Playground 代码显示了runningPropertyAnimator(withDuration:delay:options:animations:completion:) 的可能实现,以便为自动布局约束的不断变化设置动画。
import UIKit
import PlaygroundSupport
class ViewController: UIViewController {
let textView = UITextView()
lazy var heightConstraint = textView.heightAnchor.constraint(equalToConstant: 50)
override func viewDidLoad() {
view.backgroundColor = .white
view.addSubview(textView)
textView.backgroundColor = .orange
textView.isEditable = false
textView.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
textView.translatesAutoresizingMaskIntoConstraints = false
textView.topAnchor.constraint(equalToSystemSpacingBelow: view.layoutMarginsGuide.topAnchor, multiplier: 1).isActive = true
textView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor).isActive = true
textView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor).isActive = true
heightConstraint.isActive = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(doIt(_:)))
textView.addGestureRecognizer(tapGesture)
}
@objc func doIt(_ sender: UITapGestureRecognizer) {
heightConstraint.constant = heightConstraint.constant == 50 ? 150 : 50
UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 2, delay: 0, options: [], animations: {
self.view.layoutIfNeeded()
})
}
}
PlaygroundPage.current.liveView = ViewController()