1

I have implemented a dragable UIButton in a ViewController.Apart from this dragable button I also have two UIButtons which are supposed to be detected when i drag a Button over them and change the title of static button.How can i achieve this?

this is how dragable button is implemented.

@interface ButtonAnimationViewController : UIViewController

@property (weak, nonatomic) IBOutlet UIButton *firstButton; // dragable button
@property (weak, nonatomic) IBOutlet UIButton *oneButton;   //normal button
@property (weak, nonatomic) IBOutlet UIButton *twoButton;   // normal button


@implementation ButtonAnimationViewController

 - (void)viewDidLoad
{
 [super viewDidLoad];
 [self.view addSubview:self.firstButton];
 [self.view addSubview:self.oneButton];
 [self.view addSubview:self.twoButton];

UIPanGestureRecognizer *panGesture 
    = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(dragging:)];
[self.firstButton addGestureRecognizer:panGesture];

UITapGestureRecognizer *tapGesture 
    = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(dropping:)];
tapGesture.cancelsTouchesInView = NO;
[self.oneButton addGestureRecognizer:tapGesture];
[self.twoButton addGestureRecognizer:tapGesture];


 -(void)dragging:(UIPanGestureRecognizer*)panGesture {

  if (panGesture.view != self.firstButton)
  {
    return;
  }
   if (panGesture.state == UIGestureRecognizerStateBegan || 
       panGesture.state == UIGestureRecognizerStateChanged)
  {
    CGPoint delta = [panGesture translationInView:self.view];
    CGPoint center = self.firstButton.center;
    center.x += delta.x;
    center.y += delta.y;
    self.firstButton.center = center;
    [panGesture setTranslation:CGPointZero inView:self.view];
  }
    if (panGesture.view == self.oneButton) {
    // I tried this to change the button title.
    NSString *buttonTitle = self.firstButton.titleLabel.text; 
    self.oneButton.titleLabel.text = buttonTitle;
    return;
}
    //if (panGesture.state == UIGestureRecognizerStateEnded) {
   // self.firstButton.center = center;                        
    //[panGesture setTranslation:CGPointZero inView:self.view];
}
abbood
  • 23,101
  • 16
  • 132
  • 246
iCodes
  • 1,382
  • 3
  • 21
  • 47
  • I would solve this using CGRectIntersectsRect(<#CGRect rect1#>, <#CGRect rect2#>). Using panGesture.view and self.oneButton and self.twoButton. – EricLeaf Sep 27 '13 at 13:53
  • Also this code doesn't make a lot of sense. The pan gesture is only associated with the firstButton. That initial check will never be true, nor will the last. (ie if (panGesture.view != self.firstButton) and if (panGesture.view == self.oneButton)) – EricLeaf Sep 27 '13 at 13:55
  • Also to do something when dropping, try to catch the UIGestureRecognizerStateEnded state. – EricLeaf Sep 27 '13 at 13:56

2 Answers2

1

the trick is using CGRectIntersectsRect.. that's the basic building block for knowing if one view intersects another. Take a look here for a relevant example of using that function.

here is example code:

  if (panGesture.state == UIGestureRecognizerStateBegan || 
       panGesture.state == UIGestureRecognizerStateChanged)
  {
    CGPoint delta = [panGesture translationInView:self.view];
    CGPoint center = self.firstButton.center;
    center.x += delta.x;
    center.y += delta.y;
    self.firstButton.center = center;
    [panGesture setTranslation:CGPointZero inView:self.view];
  }

  // check if there is an overlap
  NSString *draggableButtonTitle = self.firstButton.titleLabel.text;
  if (CGRectIntersectsRect(self.firstButton.frame, self.oneButton.frame)) {
      self.oneButton.titleLabel.text = draggableButtonTitle;
      // i donno if you wanna return here or continue dragging.. up to you
  } else if (CGRectIntersectsRect(self.firstButton.frame, self.twoButton.frame)) {
      self.twoButton.titleLabel.text = draggableButtonTitle;
  }
Community
  • 1
  • 1
abbood
  • 23,101
  • 16
  • 132
  • 246
  • so basically what u're trying to do is change the title of the button that's been dragged over on the point of overlap right? – abbood Sep 27 '13 at 13:50
  • actually i want to replace the title of static button by that of dragable button, when it is draged over. – iCodes Sep 27 '13 at 13:52
  • Well...I tried that , but my dragable button doesn't seem to drag now. – iCodes Sep 27 '13 at 14:16
  • that's odd.. i took out the testing code out of the brackets (see my updated code).. try commenting out my code and see if it drags.. i don't see how my code can prevent the dragging.. it's a simple if else statement that updates the title.. see if you've changed anything else.. – abbood Sep 27 '13 at 14:38
  • also do you need the title change to be instant? if not, you can put it a queue and dispatch_async like dispatch_async(yourCustomQueue, ^{ // change button title.. }); – abbood Sep 27 '13 at 14:39
0
- (void)handlePan:(UIPanGestureRecognizer *)gesture
{
    if (gesture.state == UIGestureRecognizerStateChanged) {
        CGPoint transition = [gesture translationInView:self.view];
        self.dragableButton.center = CGPointMake(self.dragableButton.center.x + transition.x, self.dragableButton.center.y + transition.y);

        CGPoint touchPoint = [gesture locationInView:self.view];
        if (CGRectContainsPoint(self.hoverButtonA.frame, touchPoint)) {
            self.hoverButtonA.alpha = 0.2;
            //change the title here?
        }
        else {
            self.hoverButtonA.alpha = 1;
            //change the title back to the origin?
        }

        //Same for the other button
        if (CGRectContainsPoint(self.hoverButtonB.frame, touchPoint)) {
            self.hoverButtonB.alpha = 0.2;
        }
        else {
            self.hoverButtonB.alpha = 1;
        }

        [gesture setTranslation:CGPointZero inView:self.view];
    }
    //I'll leave out the end part, it pretty much just like the implementation above.
}

Only add gestureRecognizer to the dragableButton, and why is there two tapGesture, instead of using target action? Besides, One GestureRecognizer can and only can have one view. add it to multiple view will not work.

Kyle Fang
  • 1,139
  • 6
  • 14