Drag, Drop and Snap with UIKit Dynamics

Mike Bluestein

The graphics and animation frameworks in iOS have always allowed application developers to create engaging user experience and when combined with touch, applications can offer very realistic effects. The introduction of UIKit Dynamics in iOS 7 continues this trend of making it easy for developers to create realistic user interactions. UIKit Dynamics brings a 2D physics engine to UIKit, allowing applications to create rich animations that are modeled with physics.

One example is a snapping effected created with UIKit Dynamics, which you can see in the following video:

[youtube http://www.youtube.com/watch?v=7z8XKViR5pQ]

Physics in iOS 7 are modeled declaratively with behaviors, which include various physics concepts such as gravity, forces, elasticity and collisions. These behaviors are then added to a UIDynamicAnimator instance which applies physics to items, such as views, that are encapsulated by the various behaviors.

Adding physics to your application with UIKit Dynamics is extremely easy and can be added with just a few lines of code. Let’s look at how to implement the example shown above to snap an image into place.

To work with UIKit Dynamics, the first thing we need need to do is create a UIDynamicAnimator:

var animator = new UIDynamicAnimator (View);

The code to drag and drop the image view is done with a UIPanGestureRecognizer as shown below:

panGesture = new UIPanGestureRecognizer ((pg) => {
  if ((pg.State == UIGestureRecognizerState.Began
    || pg.State == UIGestureRecognizerState.Changed)
    && (pg.NumberOfTouches == 1)) {

    if (snap != null)
      animator.RemoveBehavior (snap);

      var p0 = pg.LocationInView (View);

      if (dx == 0)
        dx = p0.X - imageView.Center.X;

      if (dy == 0)
        dy = p0.Y - imageView.Center.Y;

      var p1 = new PointF (p0.X - dx, p0.Y - dy);

      imageView.Center = p1;
   } else if (pg.State == UIGestureRecognizerState.Ended) {
      dx = 0;
      dy = 0;

      SnapImageIntoPlace (pg.LocationInView (View));
   }
});

When the gesture ends, we check to see if the final touch point is in the area deemed the “drop region”, and if so we will create a UISnapBehavior for the image view at the center of the snap area:

void SnapImageIntoPlace (PointF touchPoint)
{
  if (snapRect.Contains (touchPoint)) {
    if (snap != null)
      animator.RemoveBehavior (snap);

      snap = new UISnapBehavior (imageView, snapPoint);
      animator.AddBehavior (snap);
    }
}

When we add the behavior to the UIDynamicAnimator instance, the image view snaps into place with an awesome magnetic-like effect.

You can download the code for this post from my GitHub repo here to see how easy it is to add physics effects to your Xamarin.iOS applications.

Feedback usabilla icon