Tracking Multiple Touches

Discussion in 'iPhone/iPad Programming' started by Darkroom, Dec 8, 2009.

  1. Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #1
    i'm trying to produce code that will allow for tracking of touches, and have the touches' coordinates displayed in the appropriate label (touchLabel1, touchLabel2, touchLabel3) according to the touches order.

    one finger touches or moves around the screen and displays this first touch's coordinates in touchLabel1. if another finger touchs the screen, it's coordinates will be displayed in touchLabel2. if a third finger touches the screen, it's coordinates will be displayed in touchLabel3.

    now for the part i'm having difficulty with: if all 3 fingers are touching the screen and displaying their own coordinates in the appropriate label, i want to be able to have the 2nd finger removed, set it's label back to "Touch 2: {0, 0}" while the first and third fingers continue to track their positions in their appropriate labels.

    i have no idea how to write the touchesEnded: method for what i'm trying to accomplish.

    Code:
    - (void)viewDidLoad
    	{
    	labelsArray = [[NSArray alloc] initWithObjects:touchLabe1, touchLabe2, touchLabe3, nil];
    	touchesArray = [[NSMutableArray alloc] initWithCapacity:3];
    	}
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    	{
    	for (UITouch *touch in touches)
    		[touchesArray addObject:touch];
    
    	for (NSUInteger i = 0; i < 3; i++)
    		{
    		UILabel *aLabel = [labelsArray objectAtIndex:i];
    		if (i < [touchesArray count])
    			{
    			UITouch *touch = [touchesArray objectAtIndex:i];
    			NSString *point = NSStringFromCGPoint([touch locationInView:self.view]);
    			aLabel.text = [NSString stringWithFormat:@"Title %i:\n%@", i+1, point];
    			}
    		}
    	}
    
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    	{
    	for (NSUInteger i = 0; i < 3; i++)
    		{
    		UILabel *aLabel = [labelsArray objectAtIndex:i];
    		if (i < [touchesArray count])
    			{
    			UITouch *touch = [touchesArray objectAtIndex:i];
    			NSString *point = NSStringFromCGPoint([touch locationInView:self.view]);
    			aLabel.text = [NSString stringWithFormat:@"Title %i:\n%@", i+1, point];
    			}
    		}
    	}
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    	{
    	//??
    	}
    
     
  2. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    Instead of relying on the position in the array to link the touch to a label store the touch/label mapping in a dictionary or similar. Then when the second touch is removed the mapping of the third touch to the third label will be unaffected.
     
  3. thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #3
    in my "research" (read: aimlessly googling for guidance) i came across this:

    Code:
    - (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
            NSString *startPoint = NSStringFromCGPoint([[touches anyObject] locationInView:self]);  
            NSDictionary * touchData = [NSDictionary dictionaryWithObjectsandKeys: startPoint, @"location", touches, @"touch"]
            [startingLocations addObject:touchData];
            }
    
    but i'm not sure how to get the map the touches using dictionary keys.
     
  4. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    Well, get each touch from the set, create a NSString with the method you have below and insert that string and the first unused label you have into a dictionary. When the touch moves use the NSString (again created from the starting point) to update the correct label. Similarly when a touch ends remove that key (and value) from the dictionary.
     
  5. thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #5
    *solved*

    i received a lot of help for this solution, so i am posting it here for others (project attached).

    Code:
    - (void)setUpTouchHandling
    	{
    	touchToLabelMapping = CFDictionaryCreateMutable (kCFAllocatorDefault, 5, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    	availableLabels = [[NSMutableArray alloc] initWithObjects:touchLabel1, touchLabel2, touchLabel3, nil];
    	setUp = YES;
    	}
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    	{
    
    	if (!setUp)
    		[self setUpTouchHandling];
    
    	for (UITouch *touch in touches)
    		{
    		if (touch.view == self.view)
    			{
    			UILabel *label = (UILabel *)[availableLabels objectAtIndex:0];
    			CFDictionaryAddValue (touchToLabelMapping, touch, label);
    			[availableLabels removeObjectAtIndex:0];
    			label.text = NSStringFromCGPoint([touch locationInView:self.view]);
    			}
    		}
    	}
    
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    	{
    	for (UITouch *touch in touches)
    		{
    		   if (touch.view == self.view)
    			{
    			UILabel *label = (UILabel *)CFDictionaryGetValue(touchToLabelMapping, touch);
    			label.text = NSStringFromCGPoint([touch locationInView:self.view]);
    			}
    		}
    	}
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    	{
    	for (UITouch *touch in touches)
    		{
    		if (touch.view == self.view)
    			{
    			UILabel *label = (UILabel *)CFDictionaryGetValue(touchToLabelMapping, touch);
    			label.text = @"{0, 0}";
    			CFDictionaryRemoveValue (touchToLabelMapping, touch);
    			[availableLabels insertObject:label atIndex:0];
    			}
    		}
    	}
    
     

    Attached Files:

  6. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #6
    Glad you got that working. I was wondering why you decided to use the CFDictionary functions instead of an NSMutableDictionary?
     
  7. thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #7
    another (smarter) developer wrote the solution, but the following is from apple's documentation for Handling a Complex Multi-Touch Sequence:

     
  8. thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #8
    i'm noticing a memory leaks with this solution while testing on device, originating in the touchesEnded method. however, i haven't yet been able to constantly reproduce the leak and i don't see anywhere in the code that would cause a leak.

    any ideas?
     

Share This Page