Взяв ответ @ wedo и немного упростив его - вам, по сути, нужны две части информации: номер строки и столбца, который был нажат («столбец» - это порядок кнопки).
Решение 1 - Неплохое решение
Это можно сохранить на кнопке с помощью button.tag
и button.titleLabel.tag
. В -tableView:cellForRowAtIndexPath:
вы бы сделали это:
UIButton *button0 = [UIButton buttonWithType:UIButtonTypeCustom];
button0.tag = indexPath.row;
button0.titleLabel.tag = 0; // button #0 (or column 0)
[button0 addTarget:self action:@selector(cellButtonAction:)
forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button0];
Ваш cellButtonAction:
метод будет выглядеть так:
- (IBAction)answerButtonAction:(UIButton *)sender {
NSInteger row = sender.tag;
NSInteger column = sender.titleLabel.tag;
// do something
}
Решение 2 - намного лучшее решение
Вышеописанное работает и это нормально, но довольно хакерски. С другой стороны, может потребоваться 3 минуты, чтобы создать подкласс для кнопки и добавить свойство, которое может содержать значения строк и столбцов.
@interface IndexPathButton: UIButton
// NSIndexPath provides a convenient way to store an integer pair
// Note we are using cellIndex.section to store the column (or button #)
@property (strong, nonatomic) NSIndexPath *cellIndex;
@end
@implementation IndexPathButton
@end
Вы будете использовать это почти так же, как и в предыдущем решении, но сохраните значения в пользовательском свойстве, а не в тегах. В tableView:cellForRowAtIndexPath:
// You'd create a button for each column here
IndexPathButton *button0 = [IndexPathButton buttonWithType:UIButtonTypeCustom];
button0.indexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:0];
[button0 addTarget:self action:@selector(cellButtonAction:)
forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button0];
Решение 3 - Лучшее решение
UITableViewCells
обычно следует использовать делегирование для любых тяжелых работ, которые необходимо выполнить. Этот шаблон наиболее точно соответствует собственному шаблону делегата Apple для ячеек, например tableView:didSelectRowAtIndexPath
и друзья. Итак, давайте создадим базовый класс tableViewCell, который можно будет использовать для обработки любого количества элементов управления и который не нужно обмениваться indexPaths.
/** Simple protocol to allow a cell to fire any type of action from a control. */
@protocol SOTableViewCellActionDelegate <NSObject>
@required
-(void)tableViewCell:(UITableViewCell *)cell didFireActionForSender:(id)sender;
@end
@interface SOActionCell : UITableViewCell
@property (nonatomic, weak) id<SOTableViewCellActionDelegate> delegate;
@end
@implementation SOActionCell
-(void)fireAction:(id)sender
{
[self.delegate tableViewCell:self didFireActionForSender:sender];
}
@end
В -tableView:cellForRowAtIndexPath:
вы бы сделали это:
UIButton *button0 = [UIButton buttonWithType:UIButtonTypeCustom];
button0.tag = 0;
[button0 addTarget:cell action:@selector(fireAction:)
forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button0];
Затем реализуйте необходимый метод делегата в tableViewController:
-(void)tableViewCell:(UITableViewCell *)cell didFireActionForSender:(id)sender
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
NSAssert(indexPath, @"indexPath of cell shall always be found."];
if (!indexPath)
return;
// do whatever you want to do with your button action here
// using indexPath, sender tag, button title, etc.
}