Dec 10, 2009

Multi-touch interaction

Today we are going to introduce the multi-touch interaction that will extend the previous application's example.
If you haven't done, download the source code of the last version of the TestTouch application and open it with Xcode.

The multi-touch interaction is disabled by default, so in the TouchView.m file we have to enable it by writing the following piece of code (put it where you want between the keywords "@implementation TouchView" and "@end":

- (void)awakeFromNib {
    [self setMultipleTouchEnabled:YES];
}

The source code you will find into the touchesEnded we wrote last time has to be executed only on single touch, so we have to surround it with the following check code:

if (numFingers == 1) {
    // Put here the old code
    ...
}

The 'numFingers' is an NSUInteger variable initialized at the beginning of the touchesEnded method as follows:

NSUInteger numFingers = [touches count];

As multi-touch behavior let's say we want to scale the red square we have inside the main view using the pinch gesture.
First of all let's define in the TouchView.h file a helper function the we will use to calculate the scale factor:

static inline CGFloat calculateScaleFactor(CGPoint line1Start, CGPoint line1End, CGPoint line2Start, CGPoint line2End) {
    CGFloat dx1 = line1End.x - line1Start.x;
    CGFloat dy1 = line1End.y - line1Start.y;

    CGFloat dx2 = line2End.x - line2Start.x;
    CGFloat dy2 = line2End.y - line2Start.y;
   
    CGFloat line1Length = sqrt((dx1 * dx1) + (dy1 * dy1));
    CGFloat line2Length = sqrt((dx2 * dx2) + (dy2 * dy2));
   
    CGFloat scaleFactor = line1Length != 0 ? (line2Length / line1Length) : 1.0;
   
    return scaleFactor;
}

The scale factor here is defined as ratio between the lengths of the end and the start lines identifying the distances between the two fingers on the screen.

Then in the TouchView.m we have to insert the code to retrieve the positions of the fingers. This code has to be inserted into the touchesMoved method:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    if ([touches count] == 2) {
        // Retrieve the two fingers touches:
        NSArray *twoTouches = [touches allObjects];
        UITouch *first = [twoTouches objectAtIndex:0];
        UITouch *second = [twoTouches objectAtIndex:1];
       
        // Retrieve their old positions:
        CGPoint startPoint1 = [first previousLocationInView:self];
        CGPoint startPoint2 = [second previousLocationInView:self];
       
        // Retrieve their actual positions:
        CGPoint endPoint1 = [first locationInView:self];
        CGPoint endPoint2 = [second locationInView:self];
       
        // Calculate the scaling factor:
        CGFloat currentScaleFactor = calculateScaleFactor(startPoint1, startPoint2, endPoint1, endPoint2);
       
        // Apply the tranformation to the red square:
        followerView.transform = CGAffineTransformScale(followerView.transform, currentScaleFactor, currentScaleFactor);
    }
}

Now you can press the button 'Build and Go' and enjoy with scaling the red square through the pinch gesture.
You can substitute the simple red view with the UIImageView and load in it an image or a photo and enjoy scaling the photo.
Here you can find the source code of the project.

Thanks for reading and leave your comments.
Reblog this post [with Zemanta]

No comments:

Post a Comment