如何使用UIViewPropertyAnimator自动布局? [英] How to use UIViewPropertyAnimator with auto layout?

查看:119
本文介绍了如何使用UIViewPropertyAnimator自动布局?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以在网上找到 UIViewPropertyAnimator 的所有示例都使用通过设置框架而不是使用自动布局布局的视图,这是通常布局视图的方式。使用自动布局时,视图会动画到我想要的位置,但之后我不确定如何将其设置回模型位置。

All the examples I could find online for UIViewPropertyAnimator use views that are laid out by setting frame rather than using auto layout, which is how views are commonly laid out. When using auto layout, the view animates to the position I want, but afterwards I am not sure of how to set it back to its "model" position.

// Move a view that is constrained to the center of its superview
UIViewPropertyAnimator(duration: 1, curve: .linear) {
    testView.center = CGPoint(x: 10, y: 10)
}.startAnimation()

它显然增加了某种约束?我在执行动画之前和之后记录了容器视图的约束:

It apparently adds some kind of constraint? I logged the container view's constraints before and after performing the animation:

CONSTRAINTS BEFORE:
view: [<NSLayoutConstraint:0x618000094f00 UIView:0x7fd764004050.centerX == UIView:0x7fd75fd00000.centerX   (active)>, <NSLayoutConstraint:0x618000092de0 UIView:0x7fd764004050.centerY == UIView:0x7fd75fd00000.centerY   (active)>]

CONSTRAINTS AFTER:
view: [<NSLayoutConstraint:0x618000094f00 UIView:0x7fd764004050.centerX == UIView:0x7fd75fd00000.centerX   (active)>, <NSLayoutConstraint:0x618000092de0 UIView:0x7fd764004050.centerY == UIView:0x7fd75fd00000.centerY   (active)>, <NSLayoutConstraint:0x6100000922a0 'UIView-Encapsulated-Layout-Height' UIView:0x7fd75fd00000.height == 667   (active)>, <NSAutoresizingMaskLayoutConstraint:0x610000092570 h=-&- v=-&- 'UIView-Encapsulated-Layout-Left' UIView:0x7fd75fd00000.minX == 0   (active, names: '|':UIWindow:0x7fd75fc07110 )>, <NSAutoresizingMaskLayoutConstraint:0x610000092890 h=-&- v=-&- 'UIView-Encapsulated-Layout-Top' UIView:0x7fd75fd00000.minY == 0   (active, names: '|':UIWindow:0x7fd75fc07110 )>, <NSLayoutConstraint:0x610000091670 'UIView-Encapsulated-Layout-Width' UIView:0x7fd75fd00000.width == 375   (active)>]

这里发生了什么?我应该如何处理使用自动布局定位的视图的动画? Apple是否鼓励用户返回基于框架的布局?

What's going on here? How should I handle the animation of views that are positioned with auto layout? Is Apple encouraging users to go back to frame-based layouts?

推荐答案

您可以使用 UIViewPropertyAnimator 使用自动布局,但您需要修改约束而不是视图的框架,并在闭包内调用 layoutIfNeeded()

You can use UIViewPropertyAnimator with Auto Layout, but you need to modify the constraints instead of the view's frame and call layoutIfNeeded() inside of the closure.

第一个例子:通过修改约束来动画常量

First example: Animate by modifying constraint constant

在Storyboard中创建一个视图。创建约束以将视图的 centerX 定位为等于superview的前沿。为该约束创建 @IBOutlet 并将其命名为 centerXConstraint 。同样,创建一个 centerYConstraint ,将您的视图的 centerY 定位为其超级视图的顶部。这两个约束都应该 constant = 0

Create a view in the Storyboard. Create a constraint to position the centerX of your view equal to the leading edge of the superview. Create an @IBOutlet to that constraint and call it centerXConstraint. Similarly, create a centerYConstraint that positions the centerY of your view equal to the top of its superview. Both of these constraints should have constant = 0.

创建 @IBOutlet s到约束:

@IBOutlet weak var centerXConstraint: NSLayoutConstraint!
@IBOutlet weak var centerYConstraint: NSLayoutConstraint!

将约束的常量值设置为新位置,然后在 UIViewPropertyAnimator 内调用 view.layoutIfNeeded()

Set the constant values of the constraint to the new position and then call view.layoutIfNeeded() inside of 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

Create a view in your Storyboard (for example redView) and create an @IBOutlet to it in your code:

@IBOutlet weak var redView: UIView!

创建 @IBOutlet s到约束条件控制视图的位置

Create @IBOutlets to the constraints that control the position of your view

// 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 是一个可以配置为以各种方式控制动画的对象。这是一个完整的示例演示:

UIViewPropertyAnimator is an object that you can configure to control the animation in various ways. Here is a complete example that demonstrates:


  1. 开始动画

  2. 暂停动画

  3. 找出已完成的动画部分并将幻灯片值设置为

  4. 使用滑块刷新动画

  1. Starting an animation
  2. Pausing an animation
  3. Finding out the fraction of the animation that has completed and setting the slide value to that
  4. Scrubbing through the animation with the slider

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)
    }
}

这篇关于如何使用UIViewPropertyAnimator自动布局?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆