Search code examples
iosviewuiimageviewboundstouchesmoved

Keeping touchesMoved within bounds of view controller


I've got a jigsaw-type application where the user can pick up any of the 40 jigsaw pieces and drag them around the screen. In testing, i noticed that some users accidentally dropped the pieces outside the bounds of the screen and the pieces could not be retrieved.

How do i specify that the pieces cannot be moved outside the bounds of the view?

Thank you.


Solution

  • I tend to have a strategy that, when the touch ends, I check to see if the boundaries of the CGRect in question are outside of the superview's rect. If it is, then I animate it going back into view.

    I'm not sure how this would be implemented as I generally use UIPanGestureRecognizer for these type of behaviors which would allow me to have access to the view object that's being moved. That being said, if the view object is an ivar, it would look like something like this.

    -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    
        //note: pieceView is your ivar for the view being moved.
        CGRect screenRect = [[UIScreen mainScreen] bounds];
        void(^animationBlock)(void);  
    
        if ((pieceView.frame.origin.x + pieceView.frame.size.width) > screenRect.size.width) { //outside right side
            animationBlock = ^{
               int newXVal = (screenRect.size.width - (pieceView.frame.size.width/2));
                pieceView.center = CGPointMake(newXVal, pieceView.center.y);
            };
        }
        else if (pieceView.frame.origin.x < 0.0f) { //outside left side
            animationBlock = ^{
                int newXVal = -(pieceView.frame.size.width/2);
                pieceView.center = CGPointMake(newXVal, pieceView.center.y);
            };
        }
        else if ((pieceView.frame.origin.y + pieceView.frame.size.height) > screenRect.size.height) { //outside bottom
            animationBlock = ^{
                int newYVal = (screenRect.size.height - (pieceView.frame.size.height/2));
                pieceView.center = CGPointMake(pieceView.center.x, newYVal);
            };
        }
        else if (pieceView.frame.origin.y < 0.0f) { //outside top
            animationBlock = ^{
                int newYVal = -(pieceView.frame.size.height/2);
                pieceView.center = CGPointMake(pieceView.center.x, newYVal);
            };
        }
    
        [UIView animateWithDuration:0.2 animations:animationBlock];
    
    }
    

    If you end up using UIPanGestureRecognizer, then you can access the view you are moving by accessing the pan gesture recognizer's view property.