In Xcode 5 I have created an iPhone app with 5 "letter tiles", which can be dragged around:
The tiles are implemented as Tile class utilizing Tile.xib
(here fullscreen):
The tile.png
is a small image without shadow:
The dragged.png
is a larger image with shadow:
The latter image is displayed by touchesBegan
in Tile.m:
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
_background.image = kDragged;
[_letter setFont:[UIFont systemFontOfSize:48]];
[_value setFont:[UIFont systemFontOfSize:20]];
[self.superview bringSubviewToFront:self];
[super touchesBegan:touches withEvent:event];
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
_background.image = kTile;
[_letter setFont:[UIFont systemFontOfSize:36]];
[_value setFont:[UIFont systemFontOfSize:16]];
[super touchesEnded:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
{
_background.image = kTile;
[_letter setFont:[UIFont systemFontOfSize:36]];
[_value setFont:[UIFont systemFontOfSize:16]];
[super touchesCancelled:touches withEvent:event];
}
And dragging is done by using UIPanGestureRecognizer
in ViewController.m:
- (IBAction)dragTile:(UIPanGestureRecognizer *)recognizer
{
Tile* tile = (Tile*)recognizer.view;
UIView* parent = tile.superview;
if (recognizer.state == UIGestureRecognizerStateBegan ||
recognizer.state == UIGestureRecognizerStateChanged) {
CGPoint translation = [recognizer translationInView:parent];
[tile setCenter:CGPointMake(tile.center.x + translation.x,
tile.center.y + translation.y)];
[recognizer setTranslation:CGPointZero inView:parent];
}
}
My problem is:
When I touch a tile, its size increases and the shadow is displayed (which is okay).
But once I start dragging the tile, its size resets back to small with no shadow (which I don't understand).
I've set breakpoints at touchesEnded
and touchesCancelled
- and the latter is being hit, when dragging starts. But why and how to stop this?
As discussed in the comments, the solution to the problem is to set the cancelsTouchesInView
property of UIGestureRecognizer
to NO
so that the touchesCancelled:withEvent:
method is not called by the recognizer.
Refer to the documentation here.