Draggable Buttons and Labels

Pls anyone help me…how to move controls(like button,label.. ) from one place to another using touch events in iphone..

There are 3 possibilities nowadays on how to enable items – that is UIViews and UIControls – to be draggable.

override touchesMoved

add a target/selector for dragging control events

add a pan gesture recognizer

All those are variations on essentially the same thing: the iOS delivers touches to your app and you have more or less intelligent plumbing to calculate a moving vector. Then you apply this delta to either the frame of the thing to be moved or, more intelligently change the item’s center property.

When I started building a sample I wanted to create a UIButton subclass with the added draggability and have this button be instantiated from a XIB. Now it turns out that you can only create custom buttons like this, not rounded rect buttons like you usually do. The reason for this being that the regular initWithFrame or initWithCoder for a subclassed UIButton would need to instead create a UIRoundedRectButton (private Apple class) to look like that.

Because of this I’m abandoning the fancy-pantsy extra class and instead we’ll just take a plain empty view controller and do it all in code. Here we add a centered button and use the version of the target/action method that also gets the UIEvent so that we can calculate the movement.

Now this does not have anything to check for certain bounds. The center coordinate of any view is always stated in the coordinate system of the view’s superview. So you might want to make sure that you limit the range of values for x and y so that you cannot move the button outside of the useful area. Note that by default views don’t clip, so if the superview does not cover the entire screen you could still move outside of it. With clipping enabled the button would be clipped off when moved outside of the frame of its superview.

This case lends itself to using the target/action mechanism because it’s available for any subclass of UIControl. As long as you stick with regular controls this is a great and backwards compatible method of achieving draggability. UILabel is derived from UIView and therefore does not have the addTarget:Action:forControlEvents method. So here we need to do something else.

We could ever step backward in history and override the touch methods, or step forward and use UIGestureRecognizers (available on devices with iOS 3.2 and higher). We live in the future and way more than half of the devices out there have an iOS > 4.0. So I’ll show you how to move a UILabel by means of a gesture recognizer.

The gesture we want to use is called a “pan”. Now that you know target/action you’ll immediately recognize a very similar mechanism here, but instead of a pointer to the view and optional UIEvent actually a pointer to the gesture recognizer is delivered.

We need to enable touch delivery via userInteractionEnabled because otherwise UILabels are generally deaf to touches. It’s very practical of the gesture recognizer specialized on pans to be providing the delta movement in form of a translation. Those deltas are cumulative and so at the end of our drag handler we need to set the translation back to zero.

This would need a bit more code to be usable by users. Maybe a wiggling animation like we have it on the springboard to show that something is movable? Because how would a user suspect that he could drag something? But this should be sufficient to get you started on making your app more interactive.