Drag an Image within the Bounds of Superview
January 17, 2011
This post demonstrates how to drag an image on screen, respecting the bounds of the images superview.
The first step is to create a class that inherits from UIImageView, I’ll name the class ImageToDrag. There is only one instance variable in this class, currentPoint – a CGPoint structure which has an X and Y coordinate indicating where the touch began prior to dragging.
Here is the interface definition for ImageToDrag:
@interface ImageToDrag : UIImageView { CGPoint currentPoint; } @end |
When creating an instance of ImageToDrag, I override initWithImage, and within this method set the userInteractionEnabled property to YES to enable capturing of user events.
- (id)initWithImage:(UIImage *)image { if (self = [super initWithImage:image]) self.userInteractionEnabled = YES; return self; } |
Managing Touch Events
When a touch is detected, the first step is to store the location in the currentPoint instance variable, I do this in the method shown below:
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { // When a touch starts, get the current location in the view currentPoint = [[touches anyObject] locationInView:self]; } |
The next bit of code is where I manage moving of the image on screen – the basic premise is to move the images center point based on the current touch location.
touchesMoved begins by getting the current location. The next step is to determine where the touch is now versus currentPoint stored previously. I finish by setting the new image center after verifying, and adjusting as needed, to ensure the image is within the bounds of its superview:
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event { // Get active location upon move CGPoint activePoint = [[touches anyObject] locationInView:self]; // Determine new point based on where the touch is now located CGPoint newPoint = CGPointMake(self.center.x + (activePoint.x - currentPoint.x), self.center.y + (activePoint.y - currentPoint.y)); //-------------------------------------------------------- // Make sure we stay within the bounds of the parent view //-------------------------------------------------------- float midPointX = CGRectGetMidX(self.bounds); // If too far right... if (newPoint.x > self.superview.bounds.size.width - midPointX) newPoint.x = self.superview.bounds.size.width - midPointX; else if (newPoint.x < midPointX) // If too far left... newPoint.x = midPointX; float midPointY = CGRectGetMidY(self.bounds); // If too far down... if (newPoint.y > self.superview.bounds.size.height - midPointY) newPoint.y = self.superview.bounds.size.height - midPointY; else if (newPoint.y < midPointY) // If too far up... newPoint.y = midPointY; // Set new center location self.center = newPoint; } |
Creating an Instance of ImageToDrag
To test the class created above I create a view controller and in the loadView method define a UIView, create an instance of ImageToDrag and add the same as a subview in the current view.
- (void)loadView { [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; // Create view that will contain the dragging area UIView *subview = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 220, 150)]; subview.backgroundColor = [UIColor darkGrayColor]; // Create an instance of the image to drag ImageToDrag *img = [[ImageToDrag alloc] initWithImage:[UIImage imageNamed:@"iOSDevTips.png"]]; img.center = CGPointMake(110, 75); img.userInteractionEnabled = YES; [subview addSubview:img]; [img release]; [self.view addSubview:subview]; [subview release]; } |
Two screenshots of the completed application are below:

Source Code
You can download the Xcode project here: Drag an Image within the Bounds of Superview



