Using UIDynamic on OC is almost the same as using Swift3.0. Maybe UIDynamic is concise enough, but it still needs a lot of combined actions to achieve great effect.

Declare a physical emulator
var dynamicAnimator = UIDynamicAnimator(a)// Declare an array full of ImageViews, which can be called objects when doing simulation exercises
var imageArray = Array<UIImageView> ()// MARK -- image the iamgeV does the damping alone
let imageV: UIImageView = {
    let ima = UIImageView()
    ima.frame = CGRect(x: 0, y: 200, width: 40, height: 40)
    ima.layer.cornerRadius = 20
    ima.backgroundColor = UIColor.gray
    ima.layer.masksToBounds = true
    return ima
}()
override func viewDidLoad(a) {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.view.backgroundColor = UIColor.black
    // Initialize the physical emulator, and set the scope to the entire view
    dynamicAnimator = UIDynamicAnimator(referenceView: self.view)

    // Create 8 circles and add them to the array
    for index in 0.7 {
        let imageV = UIImageView()
        imageV.frame = CGRect(x: (index % 4) * 70, y: (index / 4) * 70 + 64, width: 60, height: 60)
        self.view.addSubview(imageV)
        imageV.backgroundColor = index / 4= =0 ? UIColor.red : UIColor.green
        imageV.layer.cornerRadius = 30
        imageV.layer.masksToBounds = true
        imageArray.append(imageV)
    }
    self.view.addSubview(imageV)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    // Here you can try one action at a time to find the effect you want to achieve

    // Declare a gravity behavior, add it to the object, here Items: followed by an array, you can use [imageV] single object, or you can use an array like I did, the following Items are the same
    let graviteImage = UIGravityBehavior(items: imageArray)
    // Add a gravity of 10
    graviteImage.magnitude = 8
    // Add a vector direction, dx: 1, dy: 1 for 45 degrees, x is 1, y is 1, this direction is the diagonal direction of their quadrilateral
    graviteImage.gravityDirection = CGVector.init(dx: 1, dy: 1)
    // Add gravity behavior to the physics emulator
    dynamicAnimator.addBehavior(graviteImage)

    // Declare a collision action applied to the object
    let  collison = UICollisionBehavior(items: imageArray)
    // The constraint is whether a collision boundary is formed at the boundary of the view where the physical emulator is located
    collison.translatesReferenceBoundsIntoBoundary = true
    // Collision behavior has a proxy, in which methods are start behavior, end behavior, and so on
    collison.collisionDelegate = self
    // Add the collision behavior to the emulator
    dynamicAnimator.addBehavior(collison)

    // It is not true that our object has no physical properties and does not bounce back after impact
    // Add attributes to the object
    let imageVLetter = UIDynamicItemBehavior(items: imageArray)
    0 has no elasticity. 1 means it can bounce back to its original position. However, there is gravity on the object, so it will not return to its original position
    imageVLetter.elasticity = 1
    / / density 0 ~
    imageVLetter.density = 3
    / / resistance
    imageVLetter.resistance = 0.5
    // Friction is 0~
    imageVLetter.friction = 0.3
    / / Angle of resistance
    imageVLetter.angularResistance = 0.2
    // Add attributes to the emulator
    dynamicAnimator.addBehavior(imageVLetter)

    SnapTo: This point is the adsorption point, where the force comes from, and the damping is the force that pulls the object, rebound
    let snapBeheavior = UISnapBehavior(item: imageV, snapTo: CGPoint(x: 160, y: 400))
    / / damping,
    snapBeheavior.damping = 0.1
    // Add adsorption behavior to emulator
    dynamicAnimator.addBehavior(snapBeheavior)
    // All the above actions can be deleted
    // dynamicAnimator.removeBehavior(snapBheavior)
    //dynamicAnimator.removeBehavior(imageVLetter)
}

     // The proxy method starts and ends
func collisionBehavior(_behavior: UICollisionBehavior, beganContactFor item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying? , at p: CGPoint) {
    print("1 beganContactFor")}func collisionBehavior(_ behavior: UICollisionBehavior, endedContactFor item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?) {
    print("2 endedContactFor")}Copy the code

I wish you all a merry Christmas!!