LE SANG
LE SANG

Reputation: 11005

Is there another way to detect views when dragging other View over it?

I use pan gesture to drag multi-views in dragging line,something like that: iOS - Drag and drop collision detection How to detect when your selected item drags over another subview?

My code:

- (void)viewDidLoad
{
    [super viewDidLoad];
    for (UIView *aView in self.view.subviews) {
        [self addGestureRecognizersToPiece:aView];
    }
}

- (void)addGestureRecognizersToPiece:(UIView *)piece
{
    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panPiece:)];
    [piece addGestureRecognizer:panGesture];
}



- (void)panPiece:(UIPanGestureRecognizer *)gestureRecognizer
{
    CGPoint dragingPoint = [gestureRecognizer locationInView:self.view];

    for (UIView *aView in self.view.subviews) {
        if (CGRectContainsPoint([aView frame], dragingPoint)) {
                aView.center = dragingPoint;
        }
    }

}

I have so many subviews so I don't want to loop all subviews in self.view, I just want to detect match views in dragging line. How to do that?

If I use [gestureRecognizer view], I just get the first View.

Thanks for help in advance!

Upvotes: 3

Views: 4017

Answers (3)

Shaniraaj
Shaniraaj

Reputation: 11

You can achieve this by using CGRectIntersectsRect(<#CGRect rect1#>, <#CGRect rect2#>)

Upvotes: 0

Nikolai Ruhe
Nikolai Ruhe

Reputation: 81878

If you just want simpler code you can use UIView's hitTest:withEvent: method to find the view at the touch location:

- (void)panPiece:(UIPanGestureRecognizer *)gestureRecognizer
{
    CGPoint draggingPoint = [gestureRecognizer locationInView:self.view];
    UIView *hitView = [self.view hitTest:draggingPoint withEvent:nil];
    if (hitView.superview == self.view)
        hitView.center = draggingPoint;
}

This assumes the subviews do not have (interactive) subviews themselves.

Upvotes: 5

jrturton
jrturton

Reputation: 119292

What you have there is the best (i.e. simplest) approach. Unless you're noticing performance issues, don't worry about it.

There are a couple of improvements you could make:

  1. If you're only interested in certain views (you mention those on a dragging line, I'm not sure what that is) then add those views to an array before you begin and just loop through that array.
  2. Break out of the loop once you've found a target (using break;).
  3. Store the last hit view and check that first - in a lot of cases, it won't have changed from the last time the method was called.

Upvotes: 1

Related Questions