Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS - UITapGestureRecognizer - Selector with Arguments

In my app I am dynamically adding images to my view at runtime. I can have multiple images on screen at the same time. Each image is loaded from an object. I have added a tapGestureRecongnizer to the image so that the appropriate method is called when I tap it.

    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageTapped:)];
    [plantImageView addGestureRecognizer:tapGesture];

My problem is that I don't know what image I have tapped. I know I can call tapGestureRecognizer.location to get the location on screen but thats not really much good to me. Ideally, I'd like to be able to pass the object that the image was loaded from into the tap gesture. However, it seems that I am only able to pass in the selector name "imageTapped:" and not its arguments.

- (IBAction)imageTapped:(Plant *)plant
{
   [self performSegueWithIdentifier:@"viewPlantDetail" sender:plant];
}

Does anyone know of a way that I can pass my object as an argument into the tapGestureRecongnizer or any other way I can get a handle on it?

Thanks

Brian

like image 413
Brian Boyle Avatar asked Mar 31 '12 23:03

Brian Boyle


1 Answers

You're almost there. UIGestureRecognizer has a view property. If you allocate and attach a gesture recognizer to each image view - just as it appears you do in the code snippet - then your gesture code (on the target) can look like this:

- (void) imageTapped:(UITapGestureRecognizer *)gr {

  UIImageView *theTappedImageView = (UIImageView *)gr.view;
}

What's less clear from the code you provided is how you associate your Plant model object with it's corresponding imageView, but it could be something like this:

NSArray *myPlants;

for (i=0; i<myPlants.count; i++) {
    Plant *myPlant = [myPlants objectAtIndex:i];
    UIImage *image = [UIImage imageNamed:myPlant.imageName];  // or however you get an image from a plant
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];  // set frame, etc.

    // important bit here...
    imageView.tag = i + 32;

    [self.view addSubview:imageView];
}

Now the gr code can do this:

- (void) imageTapped:(UITapGestureRecognizer *)gr {

  UIImageView *theTappedImageView = (UIImageView *)gr.view;
  NSInteger tag = theTappedImageView.tag;
  Plant *myPlant = [myPlants objectAtIndex:tag-32];
}
like image 186
danh Avatar answered Oct 16 '22 23:10

danh