UITableView selected indexpath value gives wrong

1k views Asked by At

Team,

I have UITableView with which have 50 plus cells count. width of each cell is 60.

when I scroll up-to 20 cell, then tap on any cell

Its gives the index-path value above cell value not click cell value

Inside CellForRowAtIndexPath

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    [[cell checkButton] addTarget:self action:@selector(checkButtonAction:) forControlEvents:UIControlEventTouchUpInside];

}

   -(void)checkButtonAction:(id)sender

    CGPoint touchPoint = [sender convertPoint:CGPointZero toView:self.tableview];

    NSIndexPath *indexPath = [self.tableview indexPathForRowAtPoint:touchPoint];

    UIButton *button = (UIButton *)sender;

 }

If selected index is 21 gives index 20, keeping index count start from zero.

The issue was observed in iOS 10.1 iphone 7 plus device, Not in simulator iPhone 7 plus iOS 10.1 (14B72)

Debugging value {length = 2, path = 0 - 14}

NSIndexPath path should be 0 - 15 but it gives 0 - 14.

4

There are 4 answers

9
Himanshu Moradiya On BEST ANSWER
[YOURBUTTON addTarget:self action:@selector(METHODNAME:event:) forControlEvents:UIControlEventTouchDown];

Button click method

-(IBAction)METHODNAME:(UIButton*)sender event:(id)event
{

    NSSet *touches = [event allTouches];

    UITouch *touch = [touches anyObject];

    CGPoint currentTouchPosition = [touch locationInView:YOUR_TABLEVIEW];

    NSIndexPath *indexPath = [YOUR_TABLEVIEW indexPathForItemAtPoint: currentTouchPosition];
   // your requirement code 
}

If any query about this code then put your comment in answer . Good Luck

Happy Coding.

1
Ronak Chaniyara On

Use below code to get NSIndexPath in UIButton click action method and it's working fine.

Try below code and check:

-(void)checkButtonAction:(id)sender

      UIButton *btn = (UIButton *)sender;

      CGPoint origin = btn.frame.origin;
      CGPoint touchPoint = [btn.superview convertPoint:origin toView:self.tableview];

      NSIndexPath *indexPath = [self.tableview indexPathForRowAtPoint:touchPoint];

}
4
Gurinder Batth On

try this first of all give the tag number to button in cellForRowAtIndexPath Method

yourButton.tag = indexPath.row;


[YOURBUTTON addTarget:self action:@selector(checkButtonAction:) forControlEvents:UIControlEventTouchUpInside]

and the fetch like this

-(void)checkButtonAction:(id)sender

     UIButton * button = (UIButton *)sender;
     int indexPathOfCell = sender.tag;
}
0
appleBoy21 On

As mahesh pointed out a problem with Gurinder Batth solution that its not possible to get section information of indexPath. So I would like to add an answer.

Create new objective-C class inheriting from UITableViewCell. Lets say "MyTableViewCell"

Now modify MyTableViewCell.h by creating IBOutlet of UIButton (by control + click + dragging from UIButton to MyTableViewCell.h)

#import <UIKit/UIKit.h>

@class MyTableViewCell;
@protocol MyTableViewCellDelegate <NSObject>
- (void)checkButtonClicked:(MyTableViewCell *)cell;
@end

@interface MyTableViewCell : UITableViewCell

@property (weak, nonatomic) id <MyTableViewCellDelegate> delegate;
@property (weak, nonatomic) IBOutlet UIButton *checkButton;

@end

Then modify MyTableViewCell.m by creating IBAction of UIButton (by control + click + dragging from UIButton to MyTableViewCell.m)

@implementation MyTableViewCell

- (void)awakeFromNib {
    [super awakeFromNib];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
}

- (IBAction)checkButtonAction:(id)sender {
    [self.delegate checkButtonAction:self];
}

@end

Now open your ViewController.m File and implement protocol we have created in MyTableViewCell.h

@interface ViewController () <UITableViewDataSource, UITableViewDelegate, MyTableViewCellDelegate>

@property (weak, nonatomic) IBOutlet UITableView *myTableView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.view layoutIfNeeded];

    [self.myTableView setDataSource:self];
    [self.myTableView setDelegate:self];
}

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

    [myTableViewCell setDelegate:self];

    return myTableViewCell;
}

#pragma mark - MyTableViewCellDelegate method

- (void)checkButtonClicked:(MyTableViewCell *)cell {
    NSIndexPath *indexPath = (NSIndexPath*)[self.myTableView indexPathForCell:cell];
    // Here access row using "indexPath.row"
    // You can access section using "indexPath.section"
}

@end