2010-03-18 2 views
4

Я создал tableViewCell, включая изображение, две текстовые метки и uibutton. Кнопка назначается методу действия (например, viewButtonPused: отправитель).Как я могу получить indexPath UIButton в настраиваемом tableViewCell?

Я использую для обработки выбора строки с помощью tableView: didSelectRowAtIndexPath: так что я мог бы определить, какая строка была выбрана. Но с uibutton и его методом действия .... Как я могу сказать?

Заранее спасибо.

ответ

4

Определить делегат в классе, связанном с прототипом Cell.

// 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 

Теперь переходим к классу вы хотите сделать делегат ячейки. Вероятно, это будет подкласс UITableView. В методе cellForRowAtIndexPath убедитесь, что вы назначили делегата Ячейки себе. Затем реализуем метод, указанный в протоколе.

- (void)buttonTappedOnCell:(MyCell *)cell { 
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; 
    int row = indexPath.row; 
} 

Или, если вы предпочитаете блоки на основе подхода:

// MyCell.h

typdef void(^CellButtonTappedBlock)(MyCell *cell); 

@interface MyCell : UITableViewCell 
@property (nonatomic, copy) CellButtonTappedBlock buttonTappedBlock; 
@end 

Тогда в DataSource вашей Tableview в:

- (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 
    }]; 

} 
+0

Спасибо. Этот ответ был очень полезен. –

+0

Но как мы можем передать раздел тоже? –

+0

@ShreeshGarg Я обновил свой ответ надлежащим образом, это должно быть сделано. – jamone

0

определите одну переменную класса int SelectedRow; внутри didSelectRowAtIndexPath присвойте ей значение SelectedRow = indexPath.row;

используют эту SelectedRow переменную в стороне ваш метод действия viewButtonPused:sender

+0

Спасибо, но didSelectRowAtIndexPath не вызывается, если я не касаюсь строки, а не только кнопки. –

0

Вместо добавления кнопки в качестве подтаблицы ячейки установить его, чтобы быть cell.accessoryView. Затем используйте tableView:accessoryButtonTappedForRowWithIndexPath:, чтобы сделать свой материал, который должен выполняться, когда пользователь удаляет эту кнопку.

+0

Звучит интересно. Я уже использовал «тег». Я попробую это в следующий раз. Большое спасибо. –

17

Если Целью кнопки является UIViewController/UITableViewController или любой другой объект, который содержит ссылку на экземпляр UITableView, это будет делать красиво:

- (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 
} 

Используя этот подход позволит вам избежать дополнительных переменных экземпляра и будет хорошо работать в случае, если у вас есть несколько разделов. Однако вам нужно иметь доступ к экземпляру UITableView.

Edit:, как кто-то указал в комментариях ниже, этот подход прервал прошивку 7. Если вы все еще заинтересованы в использовании этого подхода над тегами, убедитесь, что найти UITableViewCell экземпляр правильно, т.е. циклически надзора, пока вы его не найдете.

+0

О, мне так нравится намного лучше, чем использовать теги. – jamone

+0

Гораздо лучший способ сделать этот вид thang. Я искал некоторую помощь в этом, так как у меня есть кнопка, которая просто удаляет строку таблицы (следовательно, indexPath.row изменяется, но тег остается неизменным!). +1 – a1phanumeric

+0

решение тега хорошее, но это прекрасно, когда у вас есть несколько разделов в вашем столе. – jfisk

0

Другим способом, который я использую сейчас, является подкласс UIButton и добавление свойства типа NSIndexPath. В cellForRowAtIndexPath Я присваиваю значение indexPath и его доступность в методе действий.

2
- (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); 
} 
1

Если вы непосредственно добавлены элементы на самой клетки (которые вы не должны) -

NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[sender superview] ]; 

Если вы добавили элементы на contentView клетки (что предлагаемый способ)

NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview] ]; 
3

Я знаю, что это старый поток, но я нахожу этот метод лучше, поскольку он свободен от вызовов superView (и, таким образом, когда Apple меняет иерархию представлений с новыми версиями os, она остается незатронутой) и не требует e подклассификация или использование громоздких тегов, которые могут быть испорчены, когда ячейка повторно используется.

- (void)buttonPressed:(UIButton *)sender { 
    CGPoint location = [sender convertPoint:sender.center toView:self.tableView]; 
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location]; 
    NSLog(@"%@", indexPath); 
} 
Смежные вопросы