views:

55

answers:

2

I want to call an action in two classes (a superview and a full screen subview) when the user single taps the screen. But, when I add a UITapGestureRecognizer to the subview, the one added to the superview is overridden. Is it possible to add a UITapGestureRecognizer to a subview without overriding the UITapGestureRecognizer added to the superview? If so, how can I do this?

Thanks!

Edit: From my main viewController "MyToolBerController", I'm adding the subview from another viewController as follows:

PhotoViewController *photoViewController = [[PhotoViewController alloc] initWithNibName:@"PhotoViewController" bundle:nil];
myPhotoView = photoViewController.view;
[self.view addSubview:myPhotoView]; 

I add the GestureRecognizer in the MyToolBerController like this:

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTapFrom:)];        
[singleTap setNumberOfTapsRequired:1];
singleTap.delegate = self;
[myPhotoView addGestureRecognizer:singleTap];
[singleTap release];

This all works fine, but I need to call a method in the PhotoViewController class when the view is tapped as well as in the MyToolBerController class. When I add another UITapGestureRecognizer in the photoViewController, it overrides the UITapGestureRecognizer added in the superView.

+2  A: 

In your gesture recognizer selector method, pass the information along to the subview. There's no need to have multiple gesture recognizers for the same gesture. Something like:

- (IBAction)handleSingleDoubleTap:(UIGestureRecognizer *)sender
{
    CGPoint tapPoint = [sender locationInView:sender.view.superview];
    UIView *subview = [parentView viewWithTag:100];
    [subview doSomethingWithPoint:tapPoint];
}

This of course means that your subview that needs to be notified should be given the tag 100 either in Interface Builder or in code when the view controller gets loaded.

Update based on Jonah's code:

So instead of retaining the view, retain the view controller:

PhotoViewController *photoViewController = [[PhotoViewController alloc] initWithNibName:@"PhotoViewController" bundle:nil];
self.myPhotoViewController = photoViewController;

Which means you need to declare it this way in the MyToolbarController header:

@property (nonatomic, retain) PhotoViewController *myPhotoViewController;

Then, when your gesture selector gets called, pass the message along to the view controller you retained. Something like:

- (IBAction)handleSingleTapFrom:(UIGestureRecognizer *)sender
{
    CGPoint tapPoint = [sender locationInView:sender.view.superview];
    [myPhotoViewController doSomethingWithPoint:tapPoint];
}

Of course the -doSomethingWithPoint: method is only for example. You can name and create any method you want that takes any parameter you want to pass in your PhotoViewController.

Let me know if you need further clarification.

Matt Long
Thanks for the help! Unfortunately, I'm sort of breaking the rules by adding the view of a uiviewcontroller as a subview. The second UIGestureRecognizer is added in the new UIViewController. I would like to have used the pushViewController method, but I need to view to take up only part of the screen. Will this still work?
Jonah
As long as you can get a hold of the view or its view controller with a pointer, you can send messages to it that it can respond to. You're not breaking the rules. What you're doing is fine. Your view controller can be the delegate to which your message gets sent when the gesture occurs. It does't have to be the view itself if the view has a view controller. That's the point of a view **controller** is to handle messages sent to and from the view. Just retain your view controller for your secondary view when you create it and pass your params on to it in your gesture recognizer selector.
Matt Long
That's exactly what I need. How can I get a hold of the viewController with a pointer? I've experimented using "@class myViewController" but am not really sure how to implement it correctly and I haven't been able to locate any sample code that shows how to do this. How would you recommend doing this?Thanks for the help!
Jonah
It's easiest to explain with code. Can you update your answer and paste the code that shows where you are creating your secondary view controller whose view your using as the subview?
Matt Long
Haven't tested Jason's answer but it sounds like it might be a path of lesser resistance. Though I'm glad to help you understand better how to enable your views to "talk" to each other.
Matt Long
I updated the question with some code above.
Jonah
I updated my response with code too.
Matt Long
That works! Thanks so much for your help!
Jonah
+2  A: 

Gesture recognizers can dispatch multiple actions when the gesture occurs. You can add the subview as another target of the gesture recognizer and only use a single UITapGestureRecognizer instance:

[tapRecognizer addTarget:theSubview action:@selector(whatever:)];
Jason Foreman