Basic practice of UIDynamtics

Preface

  • This article introduces various usages of UIDynamtics. From the basic UIGravityBehavior and UICollisionBehavior, these simple animation behaviors bring excellent visual experience. Later, it will introduce UISnapBehavior, UIPushBehavior and cool UIAttachmentBehavior to see how to use simple code to achieve cool effect. Of course, everyone's definition of cool It's different. Please don't delve into it. It's useless to talk more and get to the point.
  • This article has some problems I have encountered in the actual combat, I will write them in the article, and some writing methods and implementation methods that I think are good. I will show them in the article, from simple to slightly complex. This article is my personal practice and summary, which belongs to the original. If you need to reprint, please indicate the source.

UIDynamticAnimator

  • Compared with a container, the UIDynamticAnimator encapsulates the effect of animation implementation, which contains various behaviors and items, and the code implementation is very simple
  • It must be noted that a ReferenceView is equivalent to a reference object. A reference object in physics initializes a reference object. The subsequent View will move relative to this view. Remember the following
  1. When you use View as a reference, you should add the animated View to the SubViews of the View, or it will crash
  2. The animator needs to be set to Strong, otherwise it will automatically release memory. For the simplest example, you can't define animator in ViewDidLoad and other methods, otherwise it will cause a consequence, and your view will stay in place.
private lazy var animator = UIDynamicAnimator(referenceView: self.view)

UIGravityBehavior

  • UIGravityBehavior is very simple to use. You only need to define a View and give it an angle. When you add the View to Behavior, the View will move
  • The definition of UIGravityBehavior I recommend that you simply use close to define it, so you don't need to reuse it in the code. Of course, how to define it depends on you.

Here I post both methods and assign a random number to the angle property

    private lazy var gravityBehavior: UIGravityBehavior = {
        let behavior = UIGravityBehavior()
        behavior.angle = 2.0 * CGFloat.pi.arc4random
        animator.addBehavior(behavior)
        
        return behavior
    }()

	// Simply write where you need to
	gravityBehavior.addItem([items])

Non Closure implementation

let gravityBehavior = UIGravityBehavior(items: [square])
behavior.angle = 2.0 * CGFloat.pi.arc4random
animator.addBehavior(gravityBehavior)

UICollisionBehavior

  • UICollisionBehavior is also a simple and cool animation effect, which allows you to achieve elastic effect, but the default translatesreferencebounds into boundary is False, so you need to set it to True.

To make it easy to understand, I'm writing in a non Closure way

let collisionBehavior = UICollisionBehavior(items: [square])
collisionBehavior.translatesReferenceBoundsIntoBoundary = true
animator.addBehavior(collisonBehavior)

UIAttachmentBehavior and UISnapBehavior

  • UIAttachmentBehavior is a cool method. Here I combine UISnapBehavior to realize a drag ball. You can move the ball's position on the screen with your fingers. When you let it go, the ball will pop up and finally be absorbed in the place set by UISnapBehavior
  1. The first step is to move the ball with your fingers

Add gesture

let pan = UIPanGestureRecognizer(target: self, action: #selector(handleAttachmentGesture(sender:)))
        square.addGestureRecognizer(pan)

Gestures

@objc private func handleAttachmentGesture(sender: UIPanGestureRecognizer) {
        if sender.state == .began {
            let center = CGPoint(x: square.center.x, y: square.center.y)
            let attachPoint = UIOffset(horizontal: -25.0, vertical: -25.0)
            
            let attachmentBehavior = UIAttachmentBehavior(item: square, offsetFromCenter: attachPoint, attachedToAnchor: center)
            self.attachBahavior = attachmentBehavior
  
            self.animator.addBehavior(attachmentBehavior)
        } else if sender.state == .changed {
            self.attachBahavior.anchorPoint = sender.location(in: view)
        } else if sender.state == .ended {
            self.animator.removeBehavior(attachBahavior)
        }
    }

At this time, the ball will move with the movement of the fingers. With the front method, when you release your hand, the ball will fall in one direction, because the angle is random

  1. Achieve adsorption function
    The damping attribute sets the viscosity degree, and the greater the viscosity is when the damping is small
let snapBehavior = UISnapBehavior(item: square, snapTo: view.center)
snapBehavior.damping = 0.01
animator.addBehavior(snapBehavior)

Lighter ViewController

Back to the old topic, the lighter ViewController is actually to transfer the class code to its own class

  • Create a class that inherits from UIDynamticBehavior
  • Then when you use close to create a Behavior, simply copy and paste it into this class. The code is as follows
    lazy var gravityBehavior: UIGravityBehavior = {
        let behavior = UIGravityBehavior()
        behavior.angle = 2.0 * CGFloat.pi.arc4random
        
        return behavior
    }()
    
    lazy var collisionBehavior: UICollisionBehavior = {
        let behavior = UICollisionBehavior()
        behavior.translatesReferenceBoundsIntoBoundary = true
        
        return behavior
    }()
    
    private func snap(_ item: UIDynamicItem, to point: CGPoint) {
        let snap = UISnapBehavior(item: item, snapTo: point)
        snap.damping = 0.10
        
        addChildBehavior(snap)
    }
    
    func addItem(_ item: UIDynamicItem) {
        gravityBehavior.addItem(item)
        collisionBehavior.addItem(item)
    }
    
    func addItem(_ item: UIDynamicItem, snapTo point: CGPoint) {
        snap(item, to: point)
    }
    
    override init() {
        super.init()
        
        addChildBehavior(gravityBehavior)
        addChildBehavior(collisionBehavior)
    }
    
    convenience init(in animator: UIDynamicAnimator) {
        self.init()
        
        animator.addBehavior(self)
    }

  • Then use the initialization method to add the Behavior to your ChildBehavior, and then add a Behavior to the ViewController. Just want to call the addItem method

Initialize Behavior

private lazy var itemBehavior = LNItemBehavior(in: animator)

Join Item

itemBehavior.addItem(square, snapTo: view.center)

Published 5 original articles, won praise 1, visitors 426
Private letter follow

Tags: Attribute

Posted on Fri, 07 Feb 2020 23:46:38 -0800 by The Silent