您可以使用UIViewPropertyAnimator
with 自动布局,但是您需要修改约束而不是视图的框架并调用layoutIfNeeded()
封闭物内部。
第一个示例:通过修改约束来制作动画constant
在 Storyboard 中创建一个视图。创建约束来定位centerX
您的视图的边缘等于超级视图的前沿。创建一个@IBOutlet
到那个约束并称之为centerXConstraint
。同样,创建一个centerYConstraint
这定位了centerY
您的视图的顶部等于其超级视图的顶部。这两个约束都应该有constant = 0
.
Create @IBOutlet
s 到约束:
@IBOutlet weak var centerXConstraint: NSLayoutConstraint!
@IBOutlet weak var centerYConstraint: NSLayoutConstraint!
Set the constant
将约束值更改为新位置,然后调用view.layoutIfNeeded()
代替UIViewPropertyAnimator
:
// Make sure view has been laid out
view.layoutIfNeeded()
// Set new X and Y locations for the view
centerXConstraint.constant = 50
centerYConstraint.constant = 80
UIViewPropertyAnimator(duration: 1, curve: .easeInOut) {
self.view.layoutIfNeeded()
}.startAnimation()
第二个示例:通过激活新约束来制作动画
在 Storyboard 中创建一个视图(例如redView
)并创建一个@IBOutlet
在你的代码中:
@IBOutlet weak var redView: UIView!
Create @IBOutlet
控制视图位置的约束
// Outlets to the constraints set in the Storyboard
@IBOutlet weak var topConstraint: NSLayoutConstraint!
@IBOutlet weak var leadingConstraint: NSLayoutConstraint!
然后当需要制作动画时:
// Make sure view has been laid out
view.layoutIfNeeded()
// Deactivate the old constraints
topConstraint.isActive = false
leadingConstraint.isActive = false
// Active new constraints that move view to the bottom right
redView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
redView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
// Animate the change
UIViewPropertyAnimator(duration: 1, curve: .easeInOut) {
self.view.layoutIfNeeded()
}.startAnimation()
那么这比旧的更好吗?UIView
动画块?
UIViewPropertyAnimator
是一个可以配置为以各种方式控制动画的对象。这是一个完整的示例,演示了:
- 开始动画
- 暂停动画
- 找出已完成的动画部分并将幻灯片值设置为该部分
- 使用滑块拖动动画
class ViewController: UIViewController {
@IBOutlet weak var redView: UIView!
@IBOutlet weak var centerXConstraint: NSLayoutConstraint!
@IBOutlet weak var centerYConstraint: NSLayoutConstraint!
@IBOutlet weak var slider: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
slider.isHidden = true
}
var myAnimator: UIViewPropertyAnimator?
@IBAction func startAnimation(_ sender: UIButton) {
view.layoutIfNeeded()
centerXConstraint.isActive = false
centerYConstraint.isActive = false
redView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
redView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
myAnimator = UIViewPropertyAnimator(duration: 10, curve: .easeInOut) {
self.view.layoutIfNeeded()
}
myAnimator?.startAnimation()
}
@IBAction func pauseAnimation(_ sender: UIButton) {
guard let myAnimator = myAnimator else { return }
myAnimator.pauseAnimation()
print("The animation is \(String(format: "%.1f", myAnimator.fractionComplete * 100))% complete")
slider.value = Float(myAnimator.fractionComplete)
slider.isHidden = false
}
@IBAction func scrub(_ sender: UISlider) {
myAnimator?.fractionComplete = CGFloat(sender.value)
}
}