Search code examples
iosiphoneuiviewcgaffinetransformcgaffinetransformscale

Scaling custom UIView by CGAffineTransformMakeScale breaks dragging with touchesMoved


I have prepared and checked into GitHub a simple test case for dragging custom UIView:

app screenshot

It works well and dragging is implemented in the Tile.m as:

- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self];
    CGPoint previous = [touch previousLocationInView:self];
    self.frame = CGRectOffset(self.frame,
                              (location.x - previous.x),
                              (location.y - previous.y));
}

However the tiles are too large for my actual game (and I will have to adjust their scaling once the game board in UIScrollView is zoomed anyway):

app screenshot

So I scale my custom UIViews down by calling

tile.transform = CGAffineTransformMakeScale(.5, .5);

The size changes, but the tiles are suddenly dragged "twice as quickly" as needed:

app screenshot

Probably the touchesMoved code (s. above) should be adjusted, but I'm not sure what has been broken there by the transform manipulation?


Solution

  • Nevermind, I have found the solution:

    - (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
    {
        UITouch *touch = [touches anyObject];
        CGPoint location = [touch locationInView:self];
        CGPoint previous = [touch previousLocationInView:self];
    
        if (!CGAffineTransformIsIdentity(self.transform)) {
            location = CGPointApplyAffineTransform(location, self.transform);
            previous = CGPointApplyAffineTransform(previous, self.transform);
        }
    
        self.frame = CGRectOffset(self.frame,
                                  (location.x - previous.x),
                                  (location.y - previous.y));
    }