Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using UILongPressGestureRecognizer For Subviews of UIScrollview

For the past four hours, I have tried many Stack Overlow solutions but none have helped solve my problem.

Here it is,

  • I have a UIScrollView
  • Within that ScrollView there is one custom UILabel and 8 custom UIImageViews
  • I want to detect a long press
  • Something like this works

    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressDidFire:)];
    longPress.minimumPressDuration = 0.5; [scroll addGestureRecognizer:longPress]; //scroll defined elsewhere

However, if I replace the scroll with any subviews of scroll, the long press event never fires.

  1. How do I detect a long press of a subview of a scroll view?
  2. This is quite a messy hack, however, since I can detect long presses of a scroll view, is there any way where I can detect the position of the press so that I can see which specific subview is being pressed.

Also, (insert subview here).userInteractionEnabled = YES, I set this property for all my subviews of the scroll view, so this should not be a problem.

I have also tried using touchesBegan and touchesEnded method as suggested elsewhere in Stack Overflow.

Also, for the image views, I do set a new UILongPressGestureRecognizer for every custom image view, using a for loop, as I am aware of the 1 view per gesture recognizer rule.

From A First Time iOS Developer,

Graham

P.S. I'd really prefer if I could find a solution for 1. rather than the messy 2.


More Code As Requested:

In the Init of the view Controller

 UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressDidFire:)];
longPress.minimumPressDuration = 0.5;
[self.titleLabel addGestureRecognizer:longPress]; //titleLabel property initialized elsewhere
[mainView addSubview:self.titleLabel];

In a "load images" method

for (NSData * dataImg in results) {
//Does some work turning data into an image, into an image view called img
        img.delegate = self;
        img.userInteractionEnabled = YES;
        UILongPressGestureRecognizer *aLongPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressDidFire:)];
        aLongPress.minimumPressDuration = 0.5;
        [img addGestureRecognizer:aLongPress];
        [imgContainer addSubview:img];
}

Even More Code + Notes

self.view (UIView)

->scroll (UIScrollView)

->->mainView (UIView)

->->->titleLabel (UILabel)

->->->imgContainer (UIView)

->->->->images (UIImageViews)

[self.view addSubview:scroll];
[scroll addSubview:mainView];
[mainView addSubview:self.titleLabel];
[mainView addSubview:imgContainer];
[imgContainer addSubview:img]; //done 8x via for loop

Thanks to @RegularExpression's answer, I now am aware that the mainView is getting pressed, but not its subviews, so I need to find a way to display the mainView's subviews above it. :)

Another update, titleLabel works. ImageViews still don't work though. :(

like image 204
GangstaGraham Avatar asked Dec 06 '22 08:12

GangstaGraham


2 Answers

I know this is a bit late and an answer has been chosen, but in case someone else wants a nice simple solution if you've got iOS7.

Inside your delegate of the UILongPressGestureRecognizer implement the gestureRecognizer:shouldRequireFailureOfGestureRecognizer:otherGestureRecognizer selector

Check if otherGestureRecognizer is a UIPanGestureRecognizer and return YES, otherwise return NO

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if ([otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
        return YES;
    }

    return NO;
}

The scroll view will actually produce a UIScrollViewPanGestureRecognizer, which is part of the private API, but it's a subclass of UIPanGestureRecognizer so the above works fine.

To support iOS6 or below, then you'll need to loop through the gestureRecognizers of the UIScrollView, detect which one is a UIPanGestureRecognizer and perform the requireGestureRecognizerToFail selector on your UILongPressGestureRecogizer with that.

like image 189
mightymephisto Avatar answered Jan 25 '23 23:01

mightymephisto


your code seems to be fine,it should work i think.i used below code and its working fine for me.

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
longPress.delegate = (id)self;
longPress.minimumPressDuration=0.05;
imageView.userInteractionEnabled = YES;
[imageView addGestureRecognizer:longPress];

and its method,

- (IBAction)handleLongPress:(UILongPressGestureRecognizer *)sender {
   NSLog(@"detected");

if (sender.state == UIGestureRecognizerStateEnded){
     UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Alert" message:@"YES"    delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
     [alert show];
   } 
}

Here i took imageView as subview of scrollview as u said

like image 32
iSpark Avatar answered Jan 26 '23 00:01

iSpark