7

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];
     }];
esreli
  • 4,993
  • 2
  • 26
  • 40
  • 1
    may be problem with the you add subview of "few UIView animations" that so each time you have to do userintaraction of that all uiview(s)=YES; – Dhaval Bhadania Jan 08 '14 at 06:25
  • 1
    It would helpful if you could share some code with us, like the allocation of the gestureRecogniser, it's assignment to the imageView, and the `UIViewAnimation` block. – n00bProgrammer Jan 08 '14 at 06:41
  • 1
    is your UIImageView that you add the gesture recognizer to a property? Because it should be. – Woodstock Jan 08 '14 at 11:47
  • @JohnWoods yes it is, i've posted code above – esreli Jan 09 '14 at 23:10
  • @n00bProgrammer posted. anything else? – esreli Jan 09 '14 at 23:11
  • The "view" in this line of code: [view addSubview:self.cardImageView]; Did you forget to set userInteractionEnabled YES for "view"? – Bourne Jan 10 '14 at 05:57
  • @Bourne that line of code can be found in the override -(void)loadView. So 'view' in this method is actually a pointer to the UIViewController's view. Which is a UIView and I believe is default TRUE for userInteractionEnabled – esreli Jan 10 '14 at 19:25
  • Why do you alloc the UIGestureRecognizer twice (once in the imagwView and once in the completion block of the animation)? – user1459524 Jan 19 '14 at 13:53
  • I had a similar issue once and the problem was a transparent view that was stealing the touches. I discovered that by printing out the view hierarchy (po [[UIWindow keyWindow] recursiveDescription]). – user1459524 Jan 19 '14 at 14:14
  • You say "it ceases to recognize the gesture after only one tap". When will it happen ? How can you make it recur? – KudoCC Jan 21 '14 at 00:32

3 Answers3

1
[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.

Warif Akhand Rishi
  • 23,920
  • 8
  • 80
  • 107
  • you may have solved it! this problem has been killing me. Thanks - a bit more testing and if it's rock solid the bounty is yours – esreli Jan 22 '14 at 22:42
  • shoot, it happened again – esreli Jan 23 '14 at 05:28
  • Could you upload a simplified version of your project on GitHub? Are you doing `gestureReconnizer.enable = NO` anywhere? – Warif Akhand Rishi Jan 23 '14 at 10:10
  • I'd rather not upload the project but to answer your question, i'm not doing that. I can modify the question to display more code, though @Warif Akhand Rishi – esreli Jan 24 '14 at 04:45
  • it's likely you will be rewarded the bounty since this question isn't a hot topic. would you mind continued support as I work through this problem? – esreli Jan 24 '14 at 07:04
  • I want to contribute, I have lots of time nowadays. But thing is I can't reproduce the bug. I have made a project and tap is working on animated imageView as usual. – Warif Akhand Rishi Jan 24 '14 at 08:43
0

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];
                             }];  
Shamsudheen TK
  • 30,739
  • 9
  • 69
  • 102
0

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.

Anubrata Santra
  • 666
  • 5
  • 11