Is there a way to easily detect the closest UIButton to a tap location? I've currently subclasses a pan gesture, but am just having trouble figuring out how to approach this. In the past I've resized every button's frame so that there isn't empty space in between buttons, but that won't be possible in my current case.
At the moment I've successfully looped through my subviews and can detect when I am / am not on top of a button. But how can I detect the closest button when I'm not on a button?
Thanks!
Here's my code for identifying my UIButtons:
- (UIView *)identifySubview:(NSSet *)touches {
CGPoint tapLocation = [[touches anyObject] locationInView:self.view];
for (UIView *view in [self.view viewWithTag:1000].subviews) {
for (UITableViewCell *cell in view.subviews) {
for (UIView *contentView in cell.subviews) {
for (UIButton *button in contentView.subviews) {
if ([button isKindOfClass:[UIButton class]]) {
CGRect trueBounds = [button convertRect:button.bounds toView:self.view];
if (CGRectContainsPoint(trueBounds, tapLocation)) {
return button;
} else {
//How would I detect the closest button?
}
}
}
}
}
}
return nil;
}
Failing a direct hit, you could find the minimum distance to the centers of the buttons like this:
// this answers the square of the distance, to save a sqrt operation
- (CGFloat)sqDistanceFrom:(CGPoint)p0 to:(CGPoint)p1 {
CGFloat dx = p0.x - p1.x;
CGFloat dy = p0.y - p1.y;
return dx*dx + dy*dy;
}
- (UIView *)nearestViewIn:(NSArray *)array to:(CGPoint)p {
CGFloat minDistance = FLT_MAX;
UIView *nearestView = nil;
for (UIView *view in array) {
CGFloat distance = [self sqDistanceFrom:view.center to:p];
if (distance < minDistance) {
minDistance = distance;
nearestView = view;
}
}
return nearestView;
}
// call ...
[self nearestViewIn:view.subviews to:tapLocation];