Question

As simply put as possible, a UITapGestureRecognizer that I have assigned to an UIImageView will inevitably and inexplicably cease firing the method it is directed towards.

It's even stranger because sometimes it ceases to recognize the gesture after only one tap and other times it takes dozens upon dozens of taps. Every time without fail, though, it will inevitably cease.

I've tried setting the tap gesture as a strongly associated property and this had no effect.

What i've most recently tried (without success) is to, after the gesture's selector method has run it's course, I removed the gesture then re-allocated and re-initialized a new UITapGestureRecognizer and that had no effect. This leads me to believe the problem then is with the UIImageView and not the UITapGuestureRecognizer - but with that said, I have no idea.

But, i'm putting the UIImageView through a few UIView animations so perhaps that has something to do it?

Also, the UIImageView has enabled user interaction and I never disable it.

Any suggestions? I'm happy to post code if that would help. Here's some code:

Setting up the UIImageView (both the image view and the tap gesture have been made properties so that I may strongly associate them):

self.cardImageView = [[UIImageView alloc] initWithFrame:frame];
[self.cardImageView setContentMode:UIViewContentModeScaleAspectFill];
[self.cardImageView setClipsToBounds:TRUE];
[self.cardImageView setBackgroundColor:[UIColor nearBlack]];
[self.cardImageView.layer setBorderColor:[[UIColor fiftyGray]CGColor]];
[self.cardImageView.layer setBorderWidth:1.0];
[self.cardImageView setUserInteractionEnabled:TRUE];

self.imageFullScreenTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapImageView)];
[self.cardImageView addGestureRecognizer:self.imageFullScreenTap];

[view addSubview:self.cardImageView];

The animations:

[UIView animateWithDuration:0.2 animations:^
     {
         [self.cardImageView setFrame:[self frameForImageView]];

         [page setAlpha:!fullscreenTemplate];
         [saveExitButton setAlpha:!fullscreenTemplate];
         [optionsButton setAlpha:!fullscreenTemplate];

         if(fullscreenTemplate)
         {
             [self.cardImageView.layer setBorderColor:[UIColor clearColor].CGColor];
             [self.view setBackgroundColor:[UIColor blackColor]];
         }
         else
         {
             [self.cardImageView.layer setBorderColor:[UIColor fiftyGray].CGColor];
             [self.view setBackgroundColor:[UIColor clearColor]];
         }
     }
     completion:^(BOOL finished)
     {
         [scroller setScrollEnabled:!fullscreenTemplate];

         if (self.imageFullScreenTap)
         {
             [self.cardImageView removeGestureRecognizer:self.imageFullScreenTap];
             self.imageFullScreenTap = nil;
         }

         self.imageFullScreenTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapImageView)];
         [self.cardImageView addGestureRecognizer:self.imageFullScreenTap];
     }];
Was it helpful?

Solution

[UIView transitionWithView:self.cardImageView
                  duration:0.2f 
                   options:UIViewAnimationOptionAllowUserInteraction |
                        UIViewAnimationOptionLayoutSubviews
                animations:^(void) {
                    [self.cardImageView setFrame:[self frameForImageView]];
                    [page setAlpha:!fullscreenTemplate];
                    [saveExitButton setAlpha:!fullscreenTemplate];
                    [optionsButton setAlpha:!fullscreenTemplate];
                    if(fullscreenTemplate) {
                        [self.cardImageView.layer setBorderColor:[UIColor clearColor].CGColor];
                        [self.view setBackgroundColor:[UIColor blackColor]];
                    } else {
                        [self.cardImageView.layer setBorderColor:[UIColor fiftyGray].CGColor];
                        [self.view setBackgroundColor:[UIColor clearColor]];
                    }
                } completion:^(BOOL finished) {
                    [scroller setScrollEnabled:!fullscreenTemplate];
                }]; 

Above code has changed animateWithDuration:completion: method with transitionWithView:duration:options:animations:completion: method. Importent keyWord here is UIViewAnimationOptionAllowUserInteraction. This will allow userInteraction while the image is animating.

If TapGesture still stops recognising after some time, plz show me the code of your tapImageView method.

OTHER TIPS

Use UIViewAnimationOptionAllowUserInteraction and bringSubviewToFront

[view addSubview:self.cardImageView];
[view bringSubviewToFront:self.cardImageView];

The animations:

[UIView animateWithDuration:0.2
                          delay:0.0         
                        options:UIViewAnimationOptionAllowUserInteraction
                     animations:^
                             {
                                [self.cardImageView setFrame:[self frameForImageView]];

                                [page setAlpha:!fullscreenTemplate];
                                [saveExitButton setAlpha:!fullscreenTemplate];
                                [optionsButton setAlpha:!fullscreenTemplate];

                                if(fullscreenTemplate)
                                {
                                  [self.cardImageView.layer setBorderColor:[UIColor clearColor].CGColor];
                                  [self.view setBackgroundColor:[UIColor blackColor]];
                                }
                                else
                                {
                                  [self.cardImageView.layer setBorderColor:[UIColor fiftyGray].CGColor];
                                  [self.view setBackgroundColor:[UIColor clearColor]];
                                }
                             }
                             completion:^(BOOL finished)
                             {
                               [scroller setScrollEnabled:!fullscreenTemplate];

                               if (self.imageFullScreenTap)
                               {
                                 [self.cardImageView removeGestureRecognizer:self.imageFullScreenTap];
                                 self.imageFullScreenTap = nil;
                                } 

                                self.imageFullScreenTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapImageView)];
                                [self.cardImageView addGestureRecognizer:self.imageFullScreenTap];
                             }];  

If you are at some point adding the imageview to a uiscrollview then I am afraid most of the times the gesturerecognizer wont work. Or else you try by enabling userinteraction on the parentview.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top