z22
z22

Reputation: 10083

UIButton PanGesture goes out of screen

I have built a small test app to apply pan gesture on a UIButton. I applied the pan gesture successfully and succeeded in moving the button. But the problem is that I can move the button even outside the screen. How do I bound it to move only within the iPhone screen? Here is my code :

    - (void)viewDidLoad
{
    [super viewDidLoad];

    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    [panGesture setMinimumNumberOfTouches:1];
    [_shareButton addGestureRecognizer:panGesture];
}

-(IBAction)pan:(UIPanGestureRecognizer *)recognizer
{
    CGPoint trans =[recognizer translationInView:self.view];
    recognizer.view.center = CGPointMake(recognizer.view.center.x+trans.x, recognizer.view.center.y+trans.y);
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];


}

How do I restrict the button to move out of screen? I am using iOS 7, xcode 5.0.

Upvotes: 0

Views: 2078

Answers (6)

Jason
Jason

Reputation: 151

-(void)dragAction:(UIPanGestureRecognizer *)gesture{
UIView *vw = (UIView *)gesture.view;

CGPoint translation = [gesture translationInView:vw];
 if (CGRectContainsPoint(vw.frame, [gesture locationInView:vw] )) {
     vw.center = CGPointMake(vw.center.x,
                                vw.center.y);
     [gesture setTranslation:CGPointZero inView:vw];
 }
 else{
     vw.center = CGPointMake(vw.center.x,
                                vw.center.y + translation.y);
     [gesture setTranslation:CGPointZero inView:vw];
 }

Upvotes: 0

Soufian Hossam
Soufian Hossam

Reputation: 507

This will work for you .. But i wrote it in Swift :

func callMe(sender: UIPanGestureRecognizer)
{
    let translation = sender.translationInView(self.view)

    let newX = sender.view!.center.x + translation.x
    let newY = sender.view!.center.y + translation.y
    let senderWidth = sender.view!.bounds.width / 2
    let senderHight = sender.view!.bounds.height / 2

    if newX <= senderWidth
    {
        sender.view!.center = CGPoint(x: senderWidth, y: sender.view!.center.y + translation.y)
    }
    else if newX >= self.view.bounds.maxX - senderWidth
    {
        sender.view!.center = CGPoint(x: self.view.bounds.maxX - senderWidth, y: sender.view!.center.y + translation.y)
    }
    if newY <= senderHight
    {
        sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: senderHight)
    }
    else if newY >= self.view.bounds.maxY - senderHight
    {
        sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: self.view.bounds.maxY - senderHight)
    }
    else
    {
        sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: sender.view!.center.y + translation.y)
    }

    sender.setTranslation(CGPointZero, inView: self.view)
}

I Hope It helps anyone who's searching for the simplest way to do it.

Upvotes: 5

Renish Dadhaniya
Renish Dadhaniya

Reputation: 10752

Bound Limit of your Gesture Frame.It's Simply size of window.width and height.

Below is tutorial for gesture.I know it's for gaming but find your logic into this tutoril.

http://www.raywenderlich.com/2343/cocos2d-tutorial-for-ios-how-to-drag-and-drop-sprites

Disabling Pan Gesture if out of bounds detected

- (CGPoint)boundLayerPos:(CGPoint)newPos {
    CGSize winSize = [CCDirector sharedDirector].winSize;
    CGPoint retval = newPos;
    retval.x = MIN(retval.x, 0);
    retval.x = MAX(self.position.x); 
    retval.y = self.position.y;
    return retval;
}

Upvotes: 0

z22
z22

Reputation: 10083

Got it. Coded as follows :

    -(IBAction)pan:(UIPanGestureRecognizer *)recognizer
{
    CGPoint trans =[recognizer translationInView:self.view];
    CGFloat sumx = _shareButton.frame.origin.x+_shareButton.frame.size.width+5;
        CGFloat sumy = _shareButton.frame.origin.y+_shareButton.frame.size.height+5;

    CGFloat sumxm = _shareButton.frame.origin.x;
    CGFloat sumym = _shareButton.frame.origin.y;

    NSLog(@"position : %f, %f ", _shareButton.frame.origin.x, _shareButton.frame.origin.y);
    NSLog(@"screen : %f, %f ", self.view.frame.size.width ,self.view.frame.size.height);


    if (sumx > self.view.frame.size.width ||  sumy > self.view.frame.size.height )
    {
        CGRect shareButton = _shareButton.frame;
        shareButton.origin.y -= 1;
                shareButton.origin.x -= 1;
        _shareButton.frame = shareButton;

        return;
    }

    else if(sumxm < 0 || sumym < 0) {
        CGRect shareButton = _shareButton.frame;
        if(sumxm < 0)
        {
        shareButton.origin.x =0;
        }
        if(sumym < 0){
        shareButton.origin.y =0;
        }
        _shareButton.frame = shareButton;
        NSLog(@"share button : %f, %f", _shareButton.frame.origin.x, _shareButton.frame.origin.y);
        return;
    }

           recognizer.view.center = CGPointMake(recognizer.view.center.x+trans.x, recognizer.view.center.y+trans.y);

           [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];




}

Upvotes: 0

Ajay
Ajay

Reputation: 1622

Try this:

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[pan setDelegate:self];
[shareButton addGestureRecognizer:pan]; 

-(void)handlePan:(UIGestureRecognizer*)panGes{
    CGPoint point = [panGes locationInView:self.view];
    if (point.x >20 && point.x <280 && point.y<400 && point.y>30) {
        CGRect newframe = CGRectMake(point.x, point.y, shareButton.frame.size.width, shareButton.frame.size.height);
        shareButton.frame = newframe;
    }
}

and replace 20,280 & 400,30 with your respective limits.

Upvotes: 0

Prince Agrawal
Prince Agrawal

Reputation: 3607

Edit your code like this:

-(IBAction)pan:(UIPanGestureRecognizer *)recognizer
{
    CGPoint trans =[recognizer translationInView:self.view];
        if (CGRectContainsPoint([self.view frame], trans)) 
        {
            recognizer.view.center = trans;
        }
}

Here what you are doing is, you are whether point lies in view's frame or not. If it is. you are moving the center of dragged button.. let me know if this does not solve your issue.

Update 2:

Instead of implementing PanGesture, you can use onDrag event too:

- (IBAction)onButtonDrag:(id)sender forEvent:(UIEvent *)event {

    CGPoint point = [[[event allTouches] anyObject] locationInView:sender.view];
    UIControl *control = sender;
    if (CGRectContainsPoint([self.view frame], point)) {
        control.center = point;
        [self.view touchesEnded:[event allTouches] withEvent:event];
    }

}

Upvotes: 0

Related Questions