Custom UITableViewCell button action? - iphone

I've been looking around to find a solution to this, but can't seem to find one that works for me. I have a custom cell with a button inside. My problem is how do I pass the indexPath to the action method?
Right now I'm doing
[cell.showRewards addTarget:self action:#selector(myAction:) forControlEvents:UIControlEventTouchUpInside];
In my cellForRowAtIndexPath method and my method is:
-(IBAction)myAction:(id)sender{
NSIndexPath *indexPath = [self.tableView indexPathForCell:(MyCustomCell *)[sender superview]];
NSLog(#"Selected row is: %d",indexPath.row);
}
Any tips? Thanks.

cell.showRewards.tag = indexPath.row;
-(IBAction)myAction:(id)sender
{
UIButton *btn = (UIButton *)sender;
int indexrow = btn.tag;
NSLog(#"Selected row is: %d",indexrow);
}

Just want to add what I believe is the best solution of all: a category on UIView.
It's as simple as this:
- (void)somethingHappened:(id)sender
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:[sender parentCell]];
// Your code here...
}
Just use this category on UIView:
#interface UIView (ParentCell)
- (UITableViewCell *)parentCell;
#end
#implementation UIView (ParentCell)
- (UITableViewCell *)parentCell
{
UIView *superview = self.superview;
while( superview != nil ) {
if( [superview isKindOfClass:[UITableViewCell class]] )
return (UITableViewCell *)superview;
superview = superview.superview;
}
return nil;
}
#end

While I feel setting tag for the button is one way to go. You might need to write code to make sure each time the cell gets reused, the appropriate tag gets updated on the button object.
Instead I have a feeling this could work. Try this -
-(IBAction)myAction:(id)sender
{
CGPoint location = [sender locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
UITableViewCell *swipeCell = [self.tableView cellForRowAtIndexPath:indexPath];
NSLog(#"Selected row: %d", indexPath.row);
//......
}
Essentially what you are doing is getting the coordinates of where the click happened with respect to your tableView. After getting the coordinates, tableView can give you the indexPath by using the method indexPathForRowAtPoint:. You are good to go after this...
Voila, you have not just the indexPath but also the actual cell where the click happened. To get the actual data from your datasource (assuming its NSArray), you can do -
[datasource objectAtIndex:[indexPath row]];

Try this one.
cell.showRewards.tag=indextPath.row
implement this in cellforrowatindexpath tableview's method.
-(IBAction)myAction:(id)sender{
UIButton* btn=(UIButton*)sender;
NSLog(#"Selected row is: %d",btn.tag);
}

You set the button tag value = indexpath and check it in function if tag value is this do what u want

In custom UITableViewCell class:
[self.contentView addSubview:but_you];
In cellForRowAtIndexPath method you can write:
[cell.showRewards addTarget:self action:#selector(myAction:) forControlEvents:UIControlEventTouchUpInside];
cell.showRewards.tag = indexPath.row;

You can assign indexpath to button tag and access in your method like
cell.showRewards.tag = indexPath.row;
-(IBAction)myAction:(id)sender
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:[sender tag]];
NSLog(#"Selected row is: %d",indexPath.row);
}

I find it incredible that there isn't really a decent solution to this.
For whatever reason, I find the tagging methods and the 'using the visual location of the cell on the screen to identify the correct model object' outlined in the other answers a bit dirty.
Here are two different approaches to the problem:
Subclassing UITableViewCell
The solution I went with was to sub class UITableViewCell
#interface MyCustomCell : UITableViewCell
#property (nonatomic, strong) Model *myModelObject;
#end
When creating the cell in cellForRowAtIndexPath: you are likely to be using the model object to populate the cell data. In this method you can assign the model object to the cell.
And then in the button tap handler:
MatchTile *cell = (MatchTile *) sender.superview.superview;
if (cell && cell.myModelObject)
{
//Use cell.myModelObject
}
I'm not 100% happy with this solution to be honest. Attaching domain object to such a specialised UIKit component feels like bad practice.
Use Objective-C Associative Objects
If you don't want to subclass the cell there is a another bit of trickery you can use to associate the model object with the cell and retrieve it later.
To retrieve the model object from the cell, you will need a unique key to identify it. Define one like this:
static char* OBJECT_KEY = "uniqueRetrievalKey";
Add the following line to your cellForRowAtIndexPath: method when you are using the model object to populate the cell. This will associate your model object with the cell object.
objc_setAssociatedObject(cell, OBJECT_KEY, myModelObject, OBJC_ASSOCIATION_RETAIN);
And then anywhere you have a reference to that cell you can retrieve the model object using:
MyModelObject *myModelObject = (MyModelObject *) objc_getAssociatedObject(cell, OBJECT_KEY);
In reflection, although I opted for the first (because I'd already subclassed the cell), the second solution is probably a bit cleaner since it remains the responsibility of the ViewController to attach and retrieve the model object. The UITableViewCell doesn't need to know anything about it.

In [sender superview] you access not MyCustomCell, but it's contentView.
Read UITableViewCell Class Reference:
contentView
Returns the content view of the cell object. (read-only)
#property(nonatomic, readonly, retain) UIView *contentView
Discussion:
The content view of a UITableViewCell object is the default superview for content displayed by the cell. If you want to customize cells by simply adding additional views, you should add them to the content view so they will be positioned appropriately as the cell transitions into and out of editing mode.
Easiest way to modify your code is to use [[sender superview] superview].
But this will stop working if you later modify your cell and insert button in another view.
contentView appeared in iPhoneOS 2.0. Similar future modification will influence your code. That the reason why I don't suggest to use this way.

In - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method write the code below:
[cell.zoomButton addTarget:self action:#selector(navigateAction:) forControlEvents:UIControlEventTouchUpInside];
cell.zoomButton.tag=indexPath.row;
Then write a method like this:
-(IBAction)navigateAction:(id)sender
{
UIButton *btn = (UIButton *)sender;
int indexrow = btn.tag;
NSLog(#"Selected row is: %d",indexrow);
currentBook = [[bookListParser bookListArray] objectAtIndex:indexrow];
KitapDetayViewController *kitapDetayViewController;
if(IS_IPHONE_5)
{
kitapDetayViewController = [[KitapDetayViewController alloc] initWithNibName:#"KitapDetayViewController" bundle:Nil];
}
else
{
kitapDetayViewController = [[KitapDetayViewController alloc] initWithNibName:#"KitapDetayViewController_iPhone4" bundle:Nil];
}
kitapDetayViewController.detailImageUrl = currentBook.detailImageUrl;
kitapDetayViewController.bookAuthor = currentBook.bookAuthor;
kitapDetayViewController.bookName = currentBook.bookName;
kitapDetayViewController.bookDescription = currentBook.bookDescription;
kitapDetayViewController.bookNarrator=currentBook.bookNarrator;
kitapDetayViewController.bookOrderHistory=currentBook.bookOrderDate;
int byte=[currentBook.bookSizeAtByte intValue];
int mb=byte/(1024*1024);
NSString *mbString = [NSString stringWithFormat:#"%d", mb];
kitapDetayViewController.bookSize=mbString;
kitapDetayViewController.bookOrderPrice=currentBook.priceAsText;
kitapDetayViewController.bookDuration=currentBook.bookDuration;
kitapDetayViewController.chapterNameListArray=self.chapterNameListArray;
// [[bookListParser bookListArray ]release];
[self.navigationController pushViewController:kitapDetayViewController animated:YES];
}

If you want the indexPath of the button Detecting which UIButton was pressed in a UITableView describe how to.
basically the button action becomes:
- (void)checkButtonTapped:(id)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
if (indexPath != nil)
{
...
}
}

Here is the "Simplest Way" to do it (Tested on IOS11):
NSIndexPath *indexPath = [myTable indexPathForRowAtPoint:[[[sender superview] superview] center]];

Related

How to know the section number on button click of Tableview cell in a UITableView? [duplicate]

This question already has answers here:
How to know the UITableview row number
(10 answers)
Closed 9 years ago.
I have a UITableView for which I have created a custom UITableViewCell. Each row in tableview has a button. I want to know the section number on click of a button, so that I would know that from which section button has been clicked. I have already tried few things found on stack but nothing is working.
UIButton *b = sender;
NSIndexPath *path = [NSIndexPath indexPathForRow:b.tag inSection:0];
NSLog(#"Row %d - Section : %d", path.row, path.section);
Don't know what you've tried, but i might do something like this. Doing some pseudocode from memory, here.
- (void)buttonClicked:(id)sender {
CGPoint buttonOrigin = [sender frame].origin;
// this converts the coordinate system of the origin from the button's superview to the table view's coordinate system.
CGPoint originInTableView = [self.tableView convertPoint:buttonOrigin fromView:[sender superview];
// gets the row corresponding to the converted point
NSIndexPath rowIndexPath = [self.tableView indexPathForRowAtPoint:originInTableView];
NSInteger section = [rowIndexPath section];
}
If I'm thinking clearly, this gives you flexibility in case the button's not directly inside the UITableView cell. Say, if you've nested inside some intermediary view.
Sadly, there doesn't seem to be an iOS equivalent of NSTableView's rowForView:
Create a handler for button click and add it in tableView:cellForRowAtIndexPath: method
- (void)buttonPressed:(UIButton *)button{
UITableViewCell *cell = button.superView.superView;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
//Now you have indexPath of the cell
//do your stuff here
}
When you create your custom UITableViewCell in cellForRowAtIndexPath you should pass it its section as a parameter. It could look like:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
if (!cell)
{
cell = [[[MyCustomCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MyIdentifier" section:indexPath.section] autorelease];
}
return cell;
}
Now your cell knows its section and you can use it when performing click method in MyCustomCell class
Try this,
First assign section as a tag to button also add target on button in cellForRowAtIndexPath method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
[cell.btnSample setTag:indexPath.section];
[cell.btnSample addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
...
}
Get Section as tag from sender of IBAction you defined (buttonClicked here).
-(IBAction)buttonClicked:(id)sender
{
NSLog(#"Section: %d",[sender tag]);
}

How to get UITableview cell.textlabel.text value from button click?

i am a newbie to iphone development.
I am working on a project where i am having a UItableview , i placed a button in each row .
Now my UItableView have a cell.textlabel, detailLabel, and a button placed programatically.
In cell.textlabel i have some values from json(each label have different values) and just at the right corner of each row , i placed a button.
Now i want the cell.textlable.text value of that row only whose button is pressed.
I am getting the same value for each button.
So , my question is , how to get labeltext value of the specific row whose button is pressed ?
attach a tag with your button during its creation e.g. button1.tag = 9999;
in your button click action grab the button as sender
-(void)buttonaction:(UIButton*)sender
{
UITableViewCell * selectedCell = nil;
for(UITableViewCell *cell in [tableView visibleCells])
{
if([cell viewWithTag:9999] == sender)
{
selectedCell = cell;
break;
}
}
//do whatever you like with selected cell now.
}
I hope it helps!!!
Solved like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
UIButton *tableCellButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect]retain];
tableCellButton.frame = CGRectMake(200, 1, 80, 20);
[tableCellButton setTitle:#"showing" forState:UIControlStateNormal];
[tableCellButton addTarget:self action:#selector(shortcutBottonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:tableCellButton];
} NSDictionary *listing = [ self.temp objectAtIndex:indexPath.row];
cell.textLabel.text = [listing objectForKey:#"0"];
return cell;
}
-(IBAction) shortcutBottonClicked:(id)sender{
//this code solved the problem
indexPath = [self.tableView indexPathForCell:(UITableViewCell*)[sender superview]];
mlsid2 = [self.tableView cellForRowAtIndexPath:indexPath].textLabel.text;
}
I think you mean that each row in the table has a button, and any number of them can be pressed. After the user is done pressing buttons for rows, you need to get which rows of data have been pressed.
If I read you correclty then unless your table is static, it will work something like the following:
You need to have a datastructure like the one I'm assuming you have for your UITableview datasource. For example, an NSArray full of NSNumber objects, one corresponding to each row of data. When the button in a row is pressed, the corresponding NSNumber is set 1. When you need it, just iterate through the NSArray of NSNumbers to know the corresponding rows in your table's datasource that had it's button pressed.
One thing to be aware of is that UItableview cells that you see in the UI are normally reused as the user scrolls - at least this is the case if you have a variable amount of data and rows for your table (as opposed to static), so you can't rely on the UI elements, like the button, for remembering the state
in first view .h file
#
class viewController;
#import <UIKit/UIKit.h>
#interface firstViewController : UITableViewController<UITableViewDelegate, UITableViewDataSource> {
NSString *_cellTitle;
}
#end
first view .m file in didSelectRowAtIndex method add this code like
viewController *detailViewController = [[viewController alloc] initWithNibName:#"viewController" bundle:nil];
NSInteger row = [indexPath row];
_rowTitle = [_detailList objectAtIndex:row];
detailViewController._barTitle = _rowTitle ;
or you can do this in buttonPressed method
then in the second view .h section -
#interface viewController : UIViewController {
NSString *_barTitle;
}
#property (nonatomic, retain) NSString *_barTitle;
#end
synthesize this property in implementation section
in .m and under viewDidLoad method
self.navigationItem.title = _barTitle;
don't forget to import second view .h file
hope this helps

How to get Indexpath of cell in UITableView while clicking on Custom accessory Button?

I have UITableView.In that i have created custom cell with accessory button.Now by clicking on accessory button i want to create another view with edit cell functionality.For that how do i find the index path of that cell?and how do i pass the vales of that cell?
How do i call following method:
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
First thing to note here is that when you use custom accessoryView in a cell then the tableView:accessoryButtonTappedForRowWithIndexPath: delegate method would not be called. You have to add some target/action to the button you are adding as the custom accessory and handle the tap action yourself. You should add the custom accessory something like this,
UIButton *accessory = ...;
[accessory addTarget:self action:#selector(onCustomAccessoryTapped:) forControlEvents:UIControlEventTouchUpInside];
...
cell.accessoryView = accessory;
And in the onCustomAccessoryTapped: method you have to get the index path like this,
- (void)onCustomAccessoryTapped:(UIButton *)sender {
UITableViewCell *cell = (UITableViewCell *)sender.superview;
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
// Now you can do the following
[self tableView:tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
// Or you can do something else here to handle the action
}
The indexPath is passed as the second parameter to the method.
using "indexPathForCell" works as mentioned by emptystack
[yourViewController.tableView indexPathForCell: cell];
In addition if you are using tableview and a Search View, in your controller make sure to use searchDisplayController
NSIndexPath *indexPath;
NSDictionary *campaignMember;
if(self.searchDisplayController.isActive) {
indexPath = [[self.searchDisplayController searchResultsTableView] indexPathForCell: cell];
campaignMember = [self.filterResults objectAtIndex:indexPath.row];
} else {
indexPath = [self.tableView indexPathForCell: cell];
campaignMember = [self.dataRows objectAtIndex:indexPath.row];
}
NSString *id = [campaignMember objectForKey:#"Id"];
In my case "campaignMember" is a person object and I needed to get its id. "self.dataRows" is an array that holds main table data where as "self.filterResults" contains a subset or search/filter results of all the data based on search/filter criteria.

How can I keep track of the index path of a button in a table view cell?

I have a table view where each cell has a button accessory view. The table is managed by a fetched results controller and is frequently reordered. I want to be able to press one of the buttons and obtain the index path of that button's table view cell. I've been trying to get this working for days by storing the row of the button in its tag, but when the table gets reordered, the row becomes incorrect and I keep failing at reordering the tags correctly. Any new ideas on how to keep track of the button's cell's index path?
If you feel uncomfortable relying on button.superview, this method should be a little more robust than some of the other answers here:
UIButton *button = (UIButton *)sender;
CGRect buttonFrame = [button convertRect:button.bounds toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonFrame.origin];
This stopped working with iOS 7; check out Mike Weller's answer instead
- (IBAction)clickedButton:(id)sender {
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)button.superview;
UITableView *tableView = (UITableView *)cell.superview;
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
}
Or shorter:
- (IBAction)clickedButton:(id)sender {
NSIndexPath *indexPath = [(UITableView *)sender.superview.superview indexPathForCell:(UITableViewCell *)sender.superview];
}
Both are untested!
Crawling up view hierarchies with .superview (like all of the existing answers demonstrate) is a really bad way to do things. If UITableViewCell's structure changes (which has happened before) your app will break. Seeing .superview.superview in your code should set off alarm bells.
The button and its handler should be added to a custom UITableViewCell subclass and layed out there. That's where it belongs.
The cell subclass can then delegate out the button event through a standard delegate interface, or a block. You should aim for something like this:
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = ...;
// ...
cell.onButtonTapped = ^{
[self buttonSelectedAtIndexPath:indexPath];
}
// OR
cell.delegate = self;
// ...
}
(Note: if you go the block route, you will need to use a __weak self reference to prevent retain cycles, but I thought that would clutter up the example).
If you take the delegate route you would then have this delegate method to implement:
- (void)cellButtonPressed:(UITableViewCell *)cell
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
// ...
}
Your code now has full access to the appropriate context when it handles the event.
Implementing this interface on your cell class should be straightforward.
I don't know why I need to call the method superview twice to get the UITableViewCell.
Update:
Thank for Qiulang, now I got it.
"That's because SDK now has added a private class called UITableViewCellContentView for UITableViewCell, which is button's superview now." – Qiulang
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
UITableView *curTableView = (UITableView *)cell.superview;
NSIndexPath *indexPath = [curTableView indexPathForCell:cell];
I had this same issue also and built a simple recursive method that works no matter how many views deep you triggering control is.
-(NSIndexPath*)GetIndexPathFromSender:(id)sender{
if(!sender) { return nil; }
if([sender isKindOfClass:[UITableViewCell class]])
{
UITableViewCell *cell = sender;
return [self.tableView indexPathForCell:cell];
}
return [self GetIndexPathFromSender:((UIView*)[sender superview])];
}
-(void)ButtonClicked:(id)sender{
NSIndexPath *indexPath = [self GetIndexPathFromSender:sender];
}
I have created one Method for getting indexPath, Hope this will help you.
Create Button Action (aMethod:) in cellForRowAtIndexPath
-(void) aMethod:(UIButton *)sender
{
// Calling Magic Method which will return us indexPath.
NSIndexPath *indexPath = [self getButtonIndexPath:sender];
NSLog(#"IndexPath: %li", indexPath.row);
NSLog(#"IndexRow: %li", indexPath.section);
}
// Here is the Magic Method for getting button's indexPath
-(NSIndexPath *) getButtonIndexPath:(UIButton *) button
{
CGRect buttonFrame = [button convertRect:button.bounds toView:groupTable];
return [groupTable indexPathForRowAtPoint:buttonFrame.origin];
}
Use this Perfect working for me.
CGPoint center= [sender center];
CGPoint rootViewPoint = [[sender superview] convertPoint:center toView:_tableView1];
NSIndexPath *indexPath = [_tableView1 indexPathForRowAtPoint:rootViewPoint];
NSLog(#"%#",indexPath);
SWIFT 2 UPDATE
Here's how to find out which button was tapped
#IBAction func yourButton(sender: AnyObject) {
var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(position)
let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as
UITableViewCell
print(indexPath?.row)
print("Tap tap tap tap")
}

How can I get the indexPath of UIButton in a customized tableViewCell?

I created a tableViewCell the include an image, two text labels and a uibutton.
The button is allocated to an action method (e.g. viewButtonPused:sender).
I'm used to handle row selection with tableView:didSelectRowAtIndexPath: so I could tell which row was selected. But with the uibutton and its action method .... How can I tell?
Thanks in advance.
If the button's target is the UIViewController/UITableViewController or any other object that maintains a reference to the UITableView instance, this will do nicely:
- (void)viewButtonPushed:(id)sender {
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = button.superview; // adjust according to your UITableViewCell-subclass' view hierarchy
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
// use your NSIndexPath here
}
Using this approach will let you avoid extra instance variables and will work fine in case you have multiple sections. You need to have a way to access the UITableView instance though.
Edit: as someone pointed out in the comments below, this approach broke in iOS 7. If you're still interested in using this approach over tags, be sure to find the UITableViewCell instance correctly, i.e. by looping through the superviews until you find one.
Define a delegate on the class associated with the Cell's prototype.
// MyCell.h
#protocol MyCellDelegate
- (void)buttonTappedOnCell:(MyCell *)cell;
#end
#interface MyCell : UITableViewCell
#property (nonatomic, weak) id <MyCellDelegate> delegate;
#end
// MyCell.m
#implementation MyCell
- (void)buttonTapped:(id)sender {
[self.delegate buttonTappedOnCell:self];
}
}
#end
Now go to the class you want to make the Cell's delegate. This is probably going to be a UITableView subclass. In the cellForRowAtIndexPath method make sure you assign the delegate of the Cell to self. Then implement the method specified in the protocol.
- (void)buttonTappedOnCell:(MyCell *)cell {
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
int row = indexPath.row;
}
Or if you would prefer a blocks based approach:
// MyCell.h
typdef void(^CellButtonTappedBlock)(MyCell *cell);
#interface MyCell : UITableViewCell
#property (nonatomic, copy) CellButtonTappedBlock buttonTappedBlock;
#end
Then in your tableView's dataSource:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = ....
__weak typeof(self) weakSelf = self;
[cell setButtonTappedBlock:^(MyCell *cell) {
NSIndexPath *indexPath = [weakSelf.tableView indexPathForCell:cell];
// Do stuff with the indexPath
}];
}
I know this is an old thread but I find this method best as it is free from superView calls (and thus when Apple change the view hierarchy with new os versions it is left unaffected) and doesn't require subclassing or use of cumbersome tags that can get messed up when the cell is reused.
- (void)buttonPressed:(UIButton *)sender {
CGPoint location = [sender convertPoint:sender.center toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
NSLog(#"%#", indexPath);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
[cell.customCellButton addTarget:self action:#selector(customCellButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[cell.customCellButton setTag:indexPath.row];
}
- (void)customCellButtonTapped:(id)sender {
UIButton *button = (UIButton *)sender;
NSLog(#"indexPath.row: %d", button.tag);
}
If you have directly added elements on the cell itself (which you shouldnt) -
NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[sender superview] ];
If you have added elements on the contentView of the cell (which is the proposed way)
NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview] ];
define one class variable int SelectedRow; inside didSelectRowAtIndexPath assign value to it like
SelectedRow = indexPath.row;
use this SelectedRow variable in side your action method viewButtonPused:sender
Instead of adding the button as a subview of the cell set it to be cell.accessoryView.
Then use tableView:accessoryButtonTappedForRowWithIndexPath: to do your stuff that should be done when a user taps this button.
Another way that I use now is to subclass UIButton and add a property of type NSIndexPath.
On cellForRowAtIndexPath I assign the value of indexPath and its available at the action method.