Reputation: 4367
I've simple UITableView
with one section and few rows. When user clicks cell accessory button (which is connected with detailsSegue
. I want to know what cell row was it. So than I can select right object from my array and assign it to the variable from the next view.
I have used delegate method tableview:accessoryButtonTappedForRowWithIndexPath:
and assigned indexPath value to my private property myRow
. Than in prepareForSegue:sender:
method I used my self.myRow.row
value to select right object from array.
My problem is that these two methods seems to execute in wrong order. From the NSLog I can see that prepareForSegue:sender:
method is executed first and my delegate method is changing value of self.myRow
after it.
So prepareForSegue:sender:
method is always passing wrong object to the next view (the one that was tapped previously).
Sorry for my english guys. Thanks for help in advance.
-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
self.myRow = indexPath;
NSLog(@"tapped button at row: %i",self.myRow.row);
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:@"addSegue"]) {
AddViewController *avc = segue.destinationViewController;
avc.delegate = self;
}
else if ([segue.identifier isEqualToString:@"detailsSegue"]) {
NSLog(@"Segue row: %i",self.myRow.row);
Annotation *annotation = [self.viewsList objectAtIndex:self.myRow.row];
NSLog(@"Segue annotation object: %@",annotation.title);
DetailsViewController *dvc = segue.destinationViewController;
dvc.wikiKey = annotation.title;
}
}
Upvotes: 15
Views: 12991
Reputation: 1897
// I tell you a simple and a better and an easy option :-
// Solution :- You can assign tag to button of accessory view in this method of tableView
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// set accessory view
UIButton *oValidHomeAccessryBtn = [UIButton buttonWithType:UIButtonTypeCustom];
// set target of accessory view button
[oValidHomeAccessryBtn addTarget:self action:@selector(AccessoryAction:) forControlEvents:UIControlEventTouchUpInside];
// set tag of accessory view button to the row of table
oValidHomeAccessryBtn.tag =indexPath.row;
// set button to accessory view
cell.accessoryView = oValidHomeAccessryBtn ;
}
// Make the method you passed in selector and get tag value and you would get indexPath of accessory view clicked
- (void)AccessoryAction:(id)sender
{
NSLog(@"%d",[sender tag]);
}
This is the simplest way to get the indexPat of row in which you clicked the accessory view.
Upvotes: 2
Reputation: 2226
What you need to do is call the segue
programmatically from the delegate method. Assuming you're using storyboards, you'll need to unlink the segue
in the storyboard and in your delegate method use:
[self performSegueWithIdentifier: @"IdentifierNameHere" sender: self];
Upvotes: -3
Reputation: 386018
As you have discovered, the system sends you the prepareForSegue:sender:
message before it sends you the tableview:accessoryButtonTappedForRowWithIndexPath:
message.
But, when it sends you the prepareForSegue:sender:
message, the sender
argument is the UITableViewCell
containing the accessory view. You can use that to determine which row's accessory button was tapped:
else if ([segue.identifier isEqualToString:@"detailsSegue"]) {
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
Annotation *annotation = [self.viewsList objectAtIndex:indexPath.row];
DetailsViewController *dvc = segue.destinationViewController;
dvc.wikiKey = annotation.title;
}
Upvotes: 41
Reputation: 1257
The sender will be the accessory button, right? In that case you should be able to find its containing cell by going up through super views and then get the index path of that cell. I’ve used a method like this before to do the first part:
+ (UITableViewCell *)findParentCellOfView:(UIView *)view {
if (view == nil || [view isKindOfClass:[UITableViewCell class]]) {
return (UITableViewCell *)view;
}
return [self findParentCellOfView:[view superview]];
}
Upvotes: 2