简体   繁体   中英

Moving an object (UIView) in Swift with gravity/collision/elasticity already setup

I would like to create a square in swift that starts at the top of the screen and fall down to the bottom of the screen and stay there. I also would like to be able to drag it with my finger toward the top and make it fall toward the bottom of the screen again. Any tips on how to do that?

I was able to create a square that falls toward the bottom of the screen already. I was also able to move it with my finger as well. But the problem is, whenever I move it, the square just stay in the same place. Gravity/collision/elasticity don't seem to work after I move it. I want it to fall after I lift my finger off the square. See below for an excerpt of my code. There is probably something simple that I miss. Any tips would be appreciated.

import UIKit

class ViewController: UIViewController {

  var greenSquare: UIView?
  var redSquare:UIView?
  var animator: UIDynamicAnimator?

  override func viewDidLoad() {
    super.viewDidLoad()
    createFallingObject()

    func createFallingObject() {

     //remove square from superview
     redSquare?.removeFromSuperview()

     //create the shape
     var dimen = CGRect(x: 130,y: 25,width: 90,height: 90)
     redSquare = UIView(frame: dimen)
     redSquare?.backgroundColor = UIColor.red

     //then add to the screen
     self.view.addSubview(redSquare!)

     //Initialize the animator
     animator = UIDynamicAnimator(referenceView: self.view)

     //Add gravity to the squares
     let gravity = UIGravityBehavior(items: [redSquare!])
     let direction = CGVector(dx: 0.0, dy: 0.05)
     gravity.gravityDirection = direction

     //Collision
     let boundaries = UICollisionBehavior(items: [redSquare!])
     boundaries.translatesReferenceBoundsIntoBoundary = true

     //Elasticity
     let bounce = UIDynamicItemBehavior(items: [redSquare!])
     bounce.elasticity = 0.3



     // 1. create a gesture recognizer (tap gesture)
     let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))


     //add pan gesture Regcognizer to the red square
     let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan))
     redSquare?.addGestureRecognizer(panGestureRecognizer)


     animator?.addBehavior(boundaries)
     animator?.addBehavior(bounce)
     animator?.addBehavior(gravity)
    }

    //this method handle pan
    func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) {
     if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {

        let translation = gestureRecognizer.translation(in: self.view)
        // note: 'view' is optional and need to be unwrapped
        gestureRecognizer.view!.center = CGPoint(x: gestureRecognizer.view!.center.x + translation.x, y: gestureRecognizer.view!.center.y + translation.y)
        gestureRecognizer.setTranslation(CGPoint.zero, in: self.view)

        //redSquare?.frame.origin.x = translation.x
        //redSquare?.frame.origin.y = translation.y
     }
   }

   // 3. this method is called when a tap is recognized
   func handleTap(sender: UITapGestureRecognizer) {
    createFallingObject()
   }
}

You should remove the item from the UIDynamicAnimator when the pan gesture begin and add it back when it ends.

When a view is added to a dynamic animator its position should be determine by the animator and the animator alone. Removing the item from the animator will allow the view to position normally using its frame. Adding it back to the animator will cause the animator to resume positioning it from its current state.

Alternatively, if you need to the update the position of an item manually (ie not based on the physics of the animator), you should call animator.updateItem(usingCurrentState: myDynamicItem) , where myDynamicItem is the item you want to update.

thanks beyowulf. animator?.removeAllBehavior() did the trick in the pan gesture routine

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM