2

I've implemented the GMGridview in my program. I found this code on github. Click here My program is a grid view of my business' products. Each product is a custom UIButton inside a scroll view. Im looking for ways to get the location of each button (which is the product) but every time i click different buttons it still gives me the same location. I don't understand why this is. It supposed to detect what button I am clicking.

I used this code to get the location:

 CGPoint myPoint = CGPointMake (senderButton.frame.origin.x, senderButton.frame.origin.y); 
 CGPoint angelPoint= [senderButton.superview convertPoint:myPoint toView:self.view];

I've also researched some solutions to this problem but it didn't work for me, in this case.

Thank you.

tiguero
  • 11,477
  • 5
  • 43
  • 61
  • do u want to just find which button you have tapped or the location of your tap within the button? – tiguero Sep 17 '12 at 08:33
  • i need to find the location of the button i tapped. I'm getting a constant position in my logs even if i clicked on different buttons. – angelmacaraig Sep 18 '12 at 01:43

3 Answers3

1

Create button in grid manner and setTag for each of them:

here it is only 4 button

CGFloat xPoint = 0.0;
    for (int t = 0; t < 4; t ++) {
        UIButton * button = [[UIButton alloc]initWithFrame:CGRectMake(xPoint,0.0,100.0,50.0)];
        [button setTag:t];
        [button addTarget:self action:@selector('your Selector')forControlEvents:UIControlEventTouchUpInside];
        [YOURVIEW addSubview:button];
        xPoint += 100.0;
    }

Then extract each button with it's tag from the View:

    for(int j = 0;j < 4;j++)
    {
        UIButton * removeButton = (UIButton *)[self.view viewWithTag:j];
        NSLog(@"Frame : X:%.2f Y:%.2f Width:%.2f Height:%.2f",removeButton.frame.origin.x,removeButton.frame.origin.x,removeButton.frame.size.width,removeButton.frame.size.height);

        // you can get access each button's frame here...
    }
Vedchi
  • 1,200
  • 6
  • 14
  • I'm reusing the buttons like in a table view. i don't think the tags will work for me properly. Plus, i need to get the specific coordinates. I don't see how the tags will help me. Thanks the answer though! Whatever buttons I clicked, it's giving me a constant coordinate. – angelmacaraig Sep 18 '12 at 02:09
  • You want to use tags. Why not change the tags as the button is reused? You must be changing other properties on reuse. – Dancreek Mar 08 '13 at 13:47
0

Usually, it is not required to do calculations on the coordinates of your tap event to know which button you have tapped. Indeed, the senderButton argument is just telling you exactly that. You might think of associating a tag value to each button when you build your grid (e.g, a sequence number), and then use that tag in your action handler to identify the button on a more "logical" level:

As to your original question, your code seems fine. The only potential issue I see is with self.view. Which view does it identify? And have you tried passing nil so that you get coordinates in the UIWindow space?

sergio
  • 68,819
  • 11
  • 102
  • 123
  • Hi. I set it to nil but it didn't work too. It's still giving me the same coordinates whatever button i tap. – angelmacaraig Sep 18 '12 at 09:36
  • would you do: `NSLog(@"Button Info: %@", [senderButton description]);` and ensure that each time a different button is passed in? – sergio Sep 18 '12 at 10:14
0

You can edit the tapGestureUpdated method within GMGridView so that it will pass along the location of your tap (in your button's coordinates) to your delegate method:

GMGridView.h:

#pragma mark Protocol SCLGridViewActionDelegate
@protocol SCLGridViewActionDelegate <NSObject>

@required
- (void)GMGridView:(SCLGridView *)gridView didTapOnItemAtIndex:(NSInteger)index atLocation: (CGPoint) location;
@end

GMGridView.m:

#pragma mark tapgesture
- (void)tapGestureUpdated:(UITapGestureRecognizer *)tapGesture
{
       CGPoint locationTouch = [_tapGesture locationInView:self];
       NSInteger index = [self.layoutStrategy itemPositionFromLocation:locationTouch];

       if (index != kInvalidPosition) 
       {
            CGPoint locationInItem = [_tapGesture locationInView:[self cellForItemAtIndex:index]];
            [self.actionDelegate GMGridView:self didTapOnItemAtIndex:index atLocation:locationInItem];
       }
}

EDIT

If you are in the scenario where your gridView is part of a view managed by a view controller make sure your view controller conforms to the SCLGridViewActionDelegate and set your view controller as the action delegate: yourGridView.actionDelegate = self where self is your view controller. Have then implemented the didTapInItemAtIndex method implemented within your view controller.

tiguero
  • 11,477
  • 5
  • 43
  • 61
  • Hi. thanks for the code. it didn't work for me though. I tried it on my program, but the function itself is not being called when i tap the product. – angelmacaraig Sep 18 '12 at 09:34
  • 1
    did you debug through ur code? didTapOnItemAtIndex is a delegate method you need to make your class conform to the SCLGridViewActionDelegate protocol also you need to set your action delegate. There is really no reason it shouldn't work i have been using this in my code. – tiguero Sep 18 '12 at 09:51
  • 1
    note that i am passing the location of the tap within the view being tap. If you want to get the position relative to the super view just pass the locationTouch and not the locationInItem to the [self.actionDelegate GMGridView:self didTapOnItemAtIndex:index atLocation:locationInItem]; method – tiguero Sep 18 '12 at 10:06
  • Great! I guess you are pretty new here but please accept/upvote the answer if this is correct. If you have some doubt have a look to the FAQ: http://stackoverflow.com/faq. – tiguero Sep 19 '12 at 07:38