简体   繁体   中英

Detect Tap on UIImageView within UITableViewCell

I have a custom complex UITableViewCell where there are many views. I have an UIImageView within it which is visible for a specific condition. When it's visible ,

  1. I have to perform some Action when user Taps that UIImageView.

  2. I know I have to trigger a selector for this task. But I also want to pass a value to that Method (please See -(void)onTapContactAdd :(id) sender : (NSString*) uid below) that will be called as a Action of Tap on my UIImageView in UITableViewCell I am talking about. It's because , using that passed value , the called method will do it's job.

Here is what I have tried so far.

cell.AddContactImage.hidden = NO ;
cell.imageView.userInteractionEnabled = YES;

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapContactAdd::)];
[tap setNumberOfTouchesRequired:1];
[tap setNumberOfTapsRequired:1];
[tap setDelegate:self];
[cell.AddContactImage addGestureRecognizer:tap];



-(void)onTapContactAdd :(id) sender : (NSString*) uid
{
    NSLog(@"Tapped");
// Do something with uid from parameter
}

This method is not called when I tap. I have added in my header file.

Thanks for your help in advance.

Maybe not the ideal solution, but add tags to each of the UIImageViews. Then have an NSArray with the uid's corresponding to the tag values

So somewhere in your code make the array

NSArray *testArray = [NSArray arrayWithObjects:@"uid1", @"uid2", @"uid3", @"uid4", @"uid5", @"uid6", nil];

Then when you're setting up the tableview cells set the tag to the row #

//Set the tag of the imageview to be equal to the row number 
cell.imageView.tag = indexPath.row;

//Sets up taprecognizer for each imageview
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                      action:@selector(handleTap:)];
[cell.imageView addGestureRecognizer:tap];

//Enable the image to be clicked 
cell.imageView.userInteractionEnabled = YES;

Then in the method that gets called you can get the tag like this

- (void)handleTap:(UITapGestureRecognizer *)recognizer  
{    
     NSString *uid = testArray[recognizer.view.tag];    
}

Add the gesture recognizer to the cell itself.

Then in the action selector, do as following to know which view has been tapped:

-(IBAction)cellTapped:(UITapGestureRecognizer*)tap
{
    MyCustomTableViewCell* cell = tap.view;
    CGPoint point = [tap locationInView:cell.contentView];
    UIView* tappedView = [cell.contentView hitTest:point withEvent:NULL];

    if (tappedView==cell.myImageView) {
        // Do whatever you want here,
    }
    else { } // maybe you have to handle some other views here
}

A gesture recognizer will only pass one argument into an action selector: itself. So u need to pass the uid value alone.Like this.

Guessing this lies within the cellForRowAtIndexPath: method

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //code
    cell.AddContactImage.hidden = NO ;
    cell.imageView.userInteractionEnabled = YES;
    cell_Index=indexPath.row ;
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self               action:@selector(onTapContactAdd:)];   //just one arguement passed
    [tap setNumberOfTouchesRequired:1];
    [tap setNumberOfTapsRequired:1];
    [tap setDelegate:self];
    [cell.AddContactImage addGestureRecognizer:tap];
    //rest of code
}

-(void)onTapContactAdd :(NSString*) uid
{
     NSLog(@"Tapped");
     CustomCell *cell=(CustomCell *)[yourtableView cellForRowAtIndexPath:[NSIndexPath  indexPathForRow:cell_Index inSection:0]]; 
     //cell.AddContactImage will give you the respective image .
     // Do something with uid from parameter .
}

So here when you tap on the visible image in the respective custom cell,the onTapContactAdd: method gets called with the corresponding uid value(parameter) and now we have the cell.AddContactImage also accessible which i believe is why you were trying to pass it also along with the parameters . Hope it Helps!!!

you can use ALActionBlocks to add gesture to UIImageView and handle action in block

__weak ALViewController *wSelf = self;
imageView.userInteractionEnabled = YES;
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithBlock:^(UITapGestureRecognizer *weakGR) {
    NSLog(@"pan %@", NSStringFromCGPoint([weakGR locationInView:wSelf.view]));
}];
[self.imageView addGestureRecognizer:gr];

Install

pod 'ALActionBlocks'

Another one, with the indexPath , if it's ok for you to handle the tap in DataSource:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseId)! as! ...ListCell
    ...
    cell.theImage.isUserInteractionEnabled = true
    let onTap = UITapGestureRecognizer(target: self, action: #selector(onTapImage))
    onTap.numberOfTouchesRequired = 1
    onTap.numberOfTapsRequired = 1
    cell.theImage.addGestureRecognizer(onTap)
    ...
    return cell
}

func onTapImage(_ sender: UITapGestureRecognizer) {
    var cell: ...ListCell?
    var tableView: UITableView?
    var view = sender.view
    while view != nil {
        if view is ...ListCell {
            cell = view as? ...ListCell
        }
        if view is UITableView {
            tableView = view as? UITableView
        }
        view = view?.superview
    }

    if let indexPath = (cell != nil) ? tableView?.indexPath(for: cell!) : nil {
        // this is it
    }
}

You may want to make the code shorter if you have only one tableView .

Here, We have customtableviewcell both .h and .m files with two images in cell. And HomeController, which have tableview to access this cell. This is detect the Tap on both the UIImage as described.

            **CustomTableViewCell.h**

            @protocol CustomTableViewCellDelegate <NSObject>

            - (void)didTapFirstImageAtIndex:(NSInteger)index;
            -(void)didTapSettingsImagAtIndex:(NSInteger)index;

            @end


            @interface CustomTableViewCell : UITableViewCell
            {

                UITapGestureRecognizer *tapGesture;
                UITapGestureRecognizer *tapSettingsGesture;


            }

            @property (weak, nonatomic) IBOutlet UIImageView *firstImage;
            @property (weak, nonatomic) IBOutlet UIImageView *lightSettings;

            @property (nonatomic, assign) NSInteger cellIndex;
            @property (nonatomic, strong) id<CustomTableViewCellDelegate>delegate;

            **CustomTableViewCell.m**

            #import "CustomTableViewCell.h"

            @implementation CustomTableViewCell

            - (void)awakeFromNib {
                [super awakeFromNib];
                // Initialization code

                [self addGestures];
            }

            - (void)addGestures {
                tapGesture = [[UITapGestureRecognizer alloc] 
             initWithTarget:self action:@selector(didTapFirstImage:)];
                tapGesture.numberOfTapsRequired = 1;
                [_firstImage addGestureRecognizer:tapGesture];

                tapSettingsGesture = [[UITapGestureRecognizer alloc] 
           initWithTarget:self action:@selector(didTapSettingsImage:)];
                tapSettingsGesture.numberOfTapsRequired = 1;
                [_lightSettings 
            addGestureRecognizer:tapSettingsGesture];
            }

            - (void)didTapFirstImage:(UITapGestureRecognizer *)gesture 
           {
                if (_delegate) {
                    [_delegate didTapFirstImageAtIndex:_cellIndex];
                }
            }

            -(void)didTapSettingsImage: (UITapGestureRecognizer 
            *)gesture {
                if(_delegate) {
                    [_delegate didTapSettingsAtIndex:_cellIndex];
                }
            }


         **HomeController.h**

        #import <UIKit/UIKit.h>
        #import "CustomTableViewCell.h"

        @interface HomeController : CustomNavigationBarViewController 
        <UITableViewDelegate, UITableViewDataSource, 
         UIGestureRecognizerDelegate, CustomTableViewCellDelegate>

        @end

        **HomeController.m**
        ---------------------         

        #import "HomeController.h"
        #import "CustomTableViewCell.h"



        @implementation HomeController


        -(NSInteger)tableView:(UITableView *)tableView 
       numberOfRowsInSection:(NSInteger)section {

        return 2 (Number of rows) ;
         // return number of rows 
    }


         -(UITableViewCell *)tableView:(UITableView *)tableView 
     cellForRowAtIndexPath:(NSIndexPath *)indexPath
        {
           CustomTableViewCell *cell = [tableView 
            dequeueReusableCellWithIdentifier:@"cell" 
            forIndexPath:indexPath];


         cell.delegate = self;
         cell.cellIndex = indexPath.row;
         cell.firstImage.userInteractionEnabled = YES;
         cell.lightSettings.userInteractionEnabled = YES;

         return cell;
         }




        -(void)didTapFirstImageAtIndex:(NSInteger)index
        {
            NSLog(@"Index %ld ", (long)index);
            //Do whatever you want here
        }

        -(void)didTapSettingsAtIndex:(NSInteger)index
        {
            NSLog(@"Settings index %ld", (long)index);
            // Do whatever you want here with image interaction
        }



        @end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM