How do you detect how many fingers are on the screen?

Discussion in 'iOS Programming' started by MrPenguin9, May 17, 2009.

  1. MrPenguin9 macrumors member

    Joined:
    Aug 1, 2008
    #1
    How do you detect how many fingers are on the screen in touches began? I know there is "[touches count]". But that is how many fingers touched the screen at the same time, not how many finger are on the screen.

    Thanks
     
  2. CocoaPuffs macrumors 68010

    Joined:
    Aug 23, 2008
    #2
    Isn't that the same thing? Fingers touch the screen at the same time = fingers on the screen.
     
  3. MrPenguin9 thread starter macrumors member

    Joined:
    Aug 1, 2008
    #3
    No, I meant that I put 1 finger on the screen first, and then put a second finger on the screen. When I put my second finger down how do you tell how many fingers are on the screen at that time.

    Thanks
     
  4. phjo macrumors regular

    Joined:
    Jan 8, 2008
    #4
    Use this :
    Code:
    -(void)touchesBegan:(NSSet *)theTouches withEvent:(UIEvent *)event {
       NSSet *touches= [event allTouches];
    
    then [touches count]; will definitely count the number of fingers on screen, whereas [theTouches count]; will count instead the number of fingers that effectively touched the screen, triggering the event...

    The same applies to touchesMoved or touchesEnded methods...

    phjo
     
  5. MrPenguin9 thread starter macrumors member

    Joined:
    Aug 1, 2008
    #5
    It worked! :D Thank you sooo much!!

    Edit: How do you do the same thing as that, but tell how many fingers are in a certain image frame?
     
  6. BlackWolf macrumors regular

    Joined:
    Apr 9, 2009
    #6
    you have to walk through every UITouch and check what view it is on.
     
  7. mccannmarc macrumors 6502

    mccannmarc

    Joined:
    Aug 15, 2008
    Location:
    Manchester, UK
    #7
    Or if it is all on one view make CGRects for the touchable areas then test if the touch is within a rect using CGRectContainsPoint
     
  8. MrPenguin9 thread starter macrumors member

    Joined:
    Aug 1, 2008
    #8
    Yes it's all on one view. Could you post example of the code. Sorry, I don't fully understand how I would do that.

    Thanks

    Edit: I know how to use CGRectContainsPoint to see if a touch is in a image frame. But I don't know how to use CGRects to make touchable areas.
     
  9. mccannmarc macrumors 6502

    mccannmarc

    Joined:
    Aug 15, 2008
    Location:
    Manchester, UK
    #9
    A very basic example to to show you what I meant.

    Code:
    // example rect starting at position (200,200) and 100*100 pixels in size
    CGRect myRect = CGRectMake(200, 200, 100, 100);
    
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
    {
    	NSArray * touchArray = [touches allObjects];
    		
    	for (int looper = 0; looper < [touchArray count]; ++looper) 
    	{
    	    UITouch * touch = [touchArray objectAtIndex:looper];  
    	    CGPoint point = [touch locationInView: [touch view]];
    
    	    if(CGRectContainsPoint(myRect, point))
    	    {
    		//Do something because the touch was inside the rect
    	    }
               else
               {
                   //Touch wasn't in the rect
               }
    
    	}
    }
    
     
  10. MrPenguin9 thread starter macrumors member

    Joined:
    Aug 1, 2008
    #10
    Thanks. But that code only tests for how many fingers are touch the screen at the same time, I want one finger already down and when I put my second finger down I want to know how many finger are touching that square at the time that I put my second finger down.

    Thank you so much for helping me!
     
  11. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
  12. MrPenguin9 thread starter macrumors member

    Joined:
    Aug 1, 2008
    #12
    If I combine them making:
    Code:
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
    {
    	myRect = CGRectMake(60, 141, 200, 200);
    	NSArray * touchArray = [touches allObjects];
    	
    	for (int looper = 0; looper < [touchArray count]; ++looper) 
    	{
    	    UITouch * touch = [touchArray objectAtIndex:looper];  
    	    CGPoint point = [touch locationInView: [touch view]];
    		
    	    if(CGRectContainsPoint(myRect, point))
    	    {
    			NSSet *theTouches= [event allTouches];
    			mainText.text = [NSString stringWithFormat:@"%i", [theTouches count]];
    	    }
    		else
    		{
    			//Touch wasn't in the rect
    		}
    		
    	}
    }
    There is one problem: if I put one finger out of the square and then put one finger in the square then it says I have 2 fingers in the square?! How do I fix this?

    Thanks
     
  13. MrPenguin9 thread starter macrumors member

    Joined:
    Aug 1, 2008
    #13
    In case you didn't understand what I was saying, I was trying to say: There is one problem with the code above, if I first put 1 finger not in the square and then put 1 finger in the square it says that I have 2 fingers in the square, but only 1 finger is in the square. How do I fix this?

    Thanks
     
  14. fenrus110 macrumors regular

    Joined:
    Mar 24, 2008
    #14
    Look through the Touches Sample code. it's very thorough. And yes, it is that complicated.
     
  15. mccannmarc macrumors 6502

    mccannmarc

    Joined:
    Aug 15, 2008
    Location:
    Manchester, UK
    #15
    Do you actually need to know the touch count? I wouldn't get too hung up over it if not, as long as the object that you are interested in is registered as being touched then is that not enough?

    If you have multiple objects that are to be touched at once you could calculate the amount of objects being touched by having bools for each to say if they are being touched and counting how many of the objects have their touched bool set to true.

    Ive just whacked together the code below without any testing so it might not work but maybe it is something similar to that you are after?

    NOTE: you will also need to add code into the touchesMoved to check when someone drags a finger out of the square or into it and modify the SquareTouchCount variable accordingly.

    The SquareTouchCount variable *should* represent the amount of touches currently in the your defined rect

    Code:
    int SquareTouchCount = 0;
    CGRect myRect = CGRectMake(60, 141, 200, 200);
    
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
    {
    	NSArray * touchArray = [touches allObjects];
    	
    	for (int looper = 0; looper < [touchArray count]; ++looper) 
    	{
    	    UITouch * touch = [touchArray objectAtIndex:looper];  
    	    CGPoint point = [touch locationInView: [touch view]];
    		
    	    if(CGRectContainsPoint(myRect, point))
    	    {
                     SquareTouchCount++;
    	    }
    	    else
    	    {
    		 //Touch wasn't in the rect
    	    }
    		
    	}
    }
    
    -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
    {
    	NSArray * touchArray = [touches allObjects];
    	
    	for (int looper = 0; looper < [touchArray count]; ++looper) 
    	{
    	    UITouch * touch = [touchArray objectAtIndex:looper];  
    	    CGPoint point = [touch locationInView: [touch view]];
    		
    	    if(CGRectContainsPoint(myRect, point))
    	    {
                     SquareTouchCount--;
    	    }
    	    else
    	    {
    		 //wasn't in the rect
    	    }
            }
            if ([touches count] == [[event touchesForView:[(UITouch*)[touchArray objectAtIndex: 0] view]] count]) 
    	{
    	     // Sometimes we don't always get notified about all of the touches ending so this is a failsafe
    	     SquareTouchCount = 0;
    	}
    
    }
    
     
  16. MrPenguin9 thread starter macrumors member

    Joined:
    Aug 1, 2008
    #16
    Thank you!!!!! It work perfectly!!! :D:D:D Exempt for the "CGRect myRect = CGRectMake(60, 141, 200, 200);". My xcode doesn't like that so I spit it up in to "CGRect myRect;", then in the touches began I wright "myRect = CGRectMake(60, 141, 200, 200);", and then it works perfectly!

    What do you mean by "NOTE: you will also need to add code into the touchesMoved to check when someone drags a finger out of the square or into it and modify the SquareTouchCount variable accordingly."? Do you mean something like this?
    Code:
    -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
    {
    	NSArray * touchArray = [touches allObjects];
    	
    	for (int looper = 0; looper < [touchArray count]; ++looper) 
    	{
    	    UITouch * touch = [touchArray objectAtIndex:looper];  
    	    CGPoint point = [touch locationInView: [touch view]];
    		
    	    if(!CGRectContainsPoint(myRect, point))
    	    {
                     SquareTouchCount--;
    	    }
            }
    
    }
    But that doesn't work because even if it started outside of the square it will make it minus 1. How would I make it right?
     
  17. mccannmarc macrumors 6502

    mccannmarc

    Joined:
    Aug 15, 2008
    Location:
    Manchester, UK
    #17
    No it will need more logic than that but I'm sure you will figure it out if you sit and have a think about it. hint: you might want to store the previous touch location and use that in your calculation. A couple of if statements will be all you need. I'll let you figure it :D

    You should put the CGRect myRect; in your class header and then initialize it to myRect = CGRectMake(60,141,200,200); in your classes init really. Same goes for the SquareTouchCount, the only reason I put them where I did in my code example was to try and portray not to create new ones in every touch method.
     
  18. MrPenguin9 thread starter macrumors member

    Joined:
    Aug 1, 2008
    #18
    This is the best that I can come up with:
    Code:
    int SquareTouchCount = 0;
    CGRect myRect = CGRectMake(60, 141, 200, 200);
    CGPoint startTouchPosition;
    BOOL alreadyMovedOut;
    
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
    {
    	NSArray * touchArray = [touches allObjects];
            alreadyMovedOut = NO;
    	
    	for (int looper = 0; looper < [touchArray count]; ++looper) 
    	{
    	    UITouch * touch = [touchArray objectAtIndex:looper];  
    	    CGPoint point = [touch locationInView: [touch view]];
    	    startTouchPosition = [touch locationInView:self];
    		
    	    if(CGRectContainsPoint(myRect, point))
    	    {
    			SquareTouchCount++;
    			mainText.text = [NSString stringWithFormat:@"%i", SquareTouchCount];
    	    }
    	    else
    	    {
    			//Touch wasn't in the rect
    	    }
    		
    	}
    }
    
    -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
    {
    	NSArray * touchArray = [touches allObjects];
    	
    	for (int looper = 0; looper < [touchArray count]; ++looper) 
    	{
    	    UITouch * touch = [touchArray objectAtIndex:looper];  
    	    CGPoint point = [touch locationInView: [touch view]];
    		
    	    if(CGRectContainsPoint(myRect, point))
    	    {
    			SquareTouchCount--;
    	    }
    	    else
    	    {
    			//wasn't in the rect
    	    }
    	}
    	if ([touches count] == [[event touchesForView:[(UITouch*)[touchArray objectAtIndex: 0] view]] count]) 
    	{
    		// Sometimes we don't always get notified about all of the touches ending so this is a failsafe
    		SquareTouchCount = 0;
    	}
    	
    }
    
    -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
    {
    	NSArray * touchArray = [touches allObjects];
    	
    	for (int looper = 0; looper < [touchArray count]; ++looper) 
    	{
    	    UITouch * touch = [touchArray objectAtIndex:looper];  
    	    CGPoint point = [touch locationInView: [touch view]];
    
    	    if(alreadyMovedOut == NO)
    		{
    			if(!CGRectContainsPoint(myRect, point))
    			{
    				if(CGRectContainsPoint(myRect, startTouchPosition)) 
    				{
    					alreadyMovedOut = YES;
    					SquareTouchCount--;
    					startTouchPosition = [touch locationInView:self];
    					
    				}
    			}
    		}
    	}
    }
    But that's not right, there is a few problems with it, how do I fix this to make it right? Sorry if it is simple, I'm pretty new to all this multi-touch stuff.

    Thanks!
     
  19. mccannmarc macrumors 6502

    mccannmarc

    Joined:
    Aug 15, 2008
    Location:
    Manchester, UK
    #19
    Sigh, I was hoping you'd figure it! The following code should do it :)

    Code:
    -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
    {
    	NSArray* touchArray = [touches allObjects];
    	
    	for (int looper = 0; looper < [touchArray count]; ++looper) 
    	{
    		UITouch* touch = [touchArray objectAtIndex:looper];  
    		CGPoint point = [touch locationInView:[touch view]];
    		CGPoint previousPoint = [touch previousLocationInView:[touch view]];
    		
    		if((CGRectContainsPoint(myRect, point)) && (! CGRectContainsPoint(myRect, previousPoint )))
    		{
    			// Touch has moved from outside the rect into it
    			SquareTouchCount++;
    		}
    		else if((! CGRectContainsPoint(myRect, point)) && (CGRectContainsPoint(myRect, previousPoint )))
    		 {
    			// Touch has moved from inside the rect to outside it
    			SquareTouchCount--;
    		}
    		else
    		{
    			// Touch is still within the rect
    		}
    	}
    }
    
     
  20. MrPenguin9 thread starter macrumors member

    Joined:
    Aug 1, 2008
    #20
    It works perfectly! Oh, I didn't even know there was "previousLocationInView:". Thank you sooooooo much!!!!!!!!
     
  21. mccannmarc macrumors 6502

    mccannmarc

    Joined:
    Aug 15, 2008
    Location:
    Manchester, UK

Share This Page