GMGridView icon indicating copy to clipboard operation
GMGridView copied to clipboard

Adding a UIButton to GMGridViewCell's contentView

Open flexaddicted opened this issue 12 years ago • 12 comments

First of all, thank you for sharing this fantastic component. It's very cool.

Now, I'm facing a little problem and I don't know to fix it.

I've created a custom UIView called CustomView. An instance of this view is assigned to the contentView property of GMGridViewCell class within cellForItemAtIndex method.

if(!cell) {

    // create CustomView here...
    cell.contentView = customView;
}

The custom view has a UIButton as a subview. The problem is that the button seems to not respond to tap events since they are redirected to GMGridView.

Is it possible to overcome this problem? Thank you in advance.

flexaddicted avatar Apr 03 '12 10:04 flexaddicted

This as a problem with the gesture recognizers detecting taps gobbling presses on cell views.

I've gotten around this problem by modifying the GMGridView's -gestureRecognizer:shouldRecieveTouch: to return false for either the tap or long-press gestures when the touched view is a subclass of UIControl or the descendent of one.

mwyman avatar Apr 12 '12 07:04 mwyman

@mwyman Thank you very much for your reply. Do I have to use the gesture recognizer's view property and check if it's an UIControl class? Could you provide a simple snippet to reach the goal? Thank you.

flexaddicted avatar Apr 12 '12 08:04 flexaddicted

I figured out a way to do it. For the sake of completeness I post the code I'm using. Maybe someone could be interested in.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    if(gestureRecognizer == _tapGesture) {

        UIView* touchedView = [touch view];
        if([touchedView isKindOfClass:[UIButton class]]) {

            return NO;
        }
    }

    return YES;
}

flexaddicted avatar Apr 12 '12 13:04 flexaddicted

That should work in most cases. However, you should also test against the _sortingLongPressGesture, and you may want to check whether the touched view is a descendent of a UIButton (actually, I'd generalize to UIControl).


- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    if ( gestureRecognizer == _tapGesture || gestureRecognizer == _sortingLongPressGesture ) {
        if ( [touch.view isDescendantOfView:self] ) {
            // Test if the touched view is a subview of a control
            for ( UIView *view = touch.view ; view != self ; view = view.superview )
                if ( [view isKindOfClass:[UIControl class]] )
                    return NO;
        }
    }

    return YES;
}

mwyman avatar Apr 13 '12 09:04 mwyman

mwyman, nice solution!

DioNNiS avatar Apr 17 '12 17:04 DioNNiS

Hey flexaddicted, I've tried adding a UIButton as a subview of my custom view but I can't get it to appear. Any idea what's missing?

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
    view.backgroundColor = [UIColor greenColor];
    view.layer.masksToBounds = NO;
    view.layer.cornerRadius = 15;

    UIButton *plainButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [plainButton setImage:[UIImage imageNamed:@"Itsy1.jpg"] forState:UIControlStateNormal];
    [plainButton setFrame:CGRectMake(0, 0, 50, 50)];
    [plainButton setTitle:@"Button" forState:UIControlStateNormal];
    [view addSubview:plainButton];
    [view bringSubviewToFront:plainButton];

    cell.contentView = view;

ghost avatar Apr 19 '12 17:04 ghost

flexaddicted, how did you go about knowing which position in the grid view was being clicked?

mrevoir avatar May 17 '12 16:05 mrevoir

Do I have to modify your source code to add a button? If I use a XIB, do I also have to modify the grid source code? Thanks.

Ricardo1980 avatar May 17 '12 23:05 Ricardo1980

@digicub Seems ok to me. I don't know what the problem could be.

@mrevoir Could you explain what do you mean?

@Ricardo1980 You need to create a view with its button and add it as the contentView of the cell. Yes, you have to modify the code also with a xib.

flexaddicted avatar May 18 '12 07:05 flexaddicted

@flexaddicted In thinking about how to better describe my question it struck me to look at how cell deletion currently works so I'll do that as well, but I am wondering how to determine which cell in the grid contained the button that was clicked. I can see that the button is receiving the event because my selector is invoked, but I don't know which of the buttons in the grid was clicked.

mrevoir avatar May 18 '12 12:05 mrevoir

One method would be to use setTag: on your buttons when you get the cell in GMGridView:cellForItemAtIndex:, setting it to the index of the cell. Note that you will need to do this every time you recycle a cell, not just when you create the buttons.

mwyman avatar May 19 '12 00:05 mwyman

Thanks! I would love to see this merged on the master though.

exalted avatar Jun 21 '12 09:06 exalted