With Swift 5 and iOS 12.3, according to your needs, you may choose one of the 3 following ways in order to solve your problem.
#1. Using UIView
's animate(withDuration:animations:)
class method
animate(withDuration:animations:)
has the following declaration:
Animate changes to one or more views using the specified duration.
class func animate(withDuration duration: TimeInterval, animations: @escaping () -> Void)
The Playground code below shows a possible implementation of animate(withDuration:animations:)
in order to animate an Auto Layout constraint's constant change.
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. Using UIViewPropertyAnimator
's init(duration:curve:animations:)
initialiser and startAnimation()
method
init(duration:curve:animations:)
has the following declaration:
Initializes the animator with a built-in UIKit timing curve.
convenience init(duration: TimeInterval, curve: UIViewAnimationCurve, animations: (() -> Void)? = nil)
The Playground code below shows a possible implementation of init(duration:curve:animations:)
and startAnimation()
in order to animate an Auto Layout constraint's constant change.
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. Using UIViewPropertyAnimator
's runningPropertyAnimator(withDuration:delay:options:animations:completion:)
class method
runningPropertyAnimator(withDuration:delay:options:animations:completion:)
has the following declaration:
Creates and returns an animator object that begins running its animations immediately.
class func runningPropertyAnimator(withDuration duration: TimeInterval, delay: TimeInterval, options: UIViewAnimationOptions = [], animations: @escaping () -> Void, completion: ((UIViewAnimatingPosition) -> Void)? = nil) -> Self
The Playground code below shows a possible implementation of runningPropertyAnimator(withDuration:delay:options:animations:completion:)
in order to animate an Auto Layout constraint's constant change.
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()