You don't see this very often, where a deleted answer is actually correct, and the comment (likely influencing its deletion) on it is totally wrong! I'll try and improve on it.
Usually the IBAction
you want to hook up to a button is in the view controller containing the button. However if the IBAction
is in a different controller, e.g. a parent controller then drag from the button to the First Responder object and you are able to select the IBAction
in the parent controller!
As the hidden answer states, how this is implemented is the action is sent to nil, which has the effect of the responder chain (i.e. view hierarchy) being searched for the action, as follows:
[UIApplication.sharedApplication sendAction:@selector(nextObject:) to:nil from:self forEvent:nil];
An example is a custom UITableViewCell
. Add a UIButton
to the cell but you want the action to go up to a View Controller that has an embed segue to a UITableViewController
. Drag the touch up instead action to the First Responder and select the action in the container view controller. In the action to find the indexPath simply loop the visibleCells and check if the sender is isDescendantOfView
:
- (IBAction)cellButtonTapped:(id)sender{
for(UITableViewCell *cell in self.tableViewController.tableView.visibleCells){
if([sender isDescendantOfView:cell]){
NSIndexPath *indexPath = [self.tableViewController.tableView indexPathForCell:cell];
NSLog(@"tapped %@", indexPath);
}
}
}
Another example could be a reload button: say your first view controller shows an downloaded item with an IBAction
to reload it to get the latest data, then your child controller shows some detail, but you also want them to be able to reload the main item from within the detail, just add a button in the detail and drag its action to First Responder and select the reload IBAction
in the parent controller. This allows you to hook up buttons to parent actions with no additional code like delegate methods!
For this to work the action needs to be in the responder chain hierarchy or it won't be found, you can read how the chain is built up in the docs. Also note if called from code the view needs to have appeared, viewWillAppear
is too soon.