Пользовательское действие кнопки UITableViewCell? - PullRequest
9 голосов
/ 13 сентября 2011

Я искал решение, чтобы найти решение, но, похоже, не могу найти подходящее для меня. У меня есть пользовательская ячейка с кнопкой внутри. Моя проблема заключается в том, как я могу передать indexPath в метод действия?

Прямо сейчас я делаю

 [cell.showRewards addTarget:self action:@selector(myAction:) forControlEvents:UIControlEventTouchUpInside];

В моем методе cellForRowAtIndexPath мой метод:

-(IBAction)myAction:(id)sender{
NSIndexPath *indexPath = [self.tableView indexPathForCell:(MyCustomCell *)[sender superview]];
NSLog(@"Selected row is: %d",indexPath.row);
}

Есть советы? Спасибо.

Ответы [ 12 ]

8 голосов
/ 30 апреля 2013

Просто хочу добавить то, что я считаю лучшим решением из всех: категорию на UIView.

Это так просто:

- (void)somethingHappened:(id)sender
{
    NSIndexPath *indexPath = [self.tableView indexPathForCell:[sender parentCell]];

    // Your code here...
}

Просто используйте эту категорию на 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
7 голосов
/ 13 сентября 2011
cell.showRewards.tag = indexPath.row;

-(IBAction)myAction:(id)sender
{
UIButton *btn = (UIButton *)sender;
int indexrow = btn.tag;
NSLog(@"Selected row is: %d",indexrow);
}
5 голосов
/ 13 сентября 2011

Пока я чувствую, настройка tag для кнопки - это один из способов.Возможно, вам придется написать код, чтобы при каждом повторном использовании ячейки обновлялся соответствующий тег для объекта кнопки.

Вместо этого я чувствую, что это может сработать.Попробуйте это -

-(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);
//......
}

По сути, вы получаете координаты места, где произошел щелчок относительно вашего tableView.После получения координат tableView может дать вам indexPath с помощью метода indexPathForRowAtPoint:.Вы можете пойти после этого ...

Вуаля, у вас есть не только indexPath, но и действительная ячейка, где произошел щелчок.Чтобы получить фактические данные из вашего источника данных (при условии, что он NSArray), вы можете сделать -

[datasource objectAtIndex:[indexPath row]];

3 голосов
/ 13 сентября 2011

Вы устанавливаете значение тега кнопки = indexpath и проверяете его в функции, если значение тега это то, что вы хотите

3 голосов
/ 13 сентября 2011

Попробуйте это.

cell.showRewards.tag=indextPath.row

реализуйте это в методе cellforrowatindexpath tableview.

-(IBAction)myAction:(id)sender{
UIButton* btn=(UIButton*)sender;
NSLog(@"Selected row is: %d",btn.tag);
}
2 голосов
/ 13 сентября 2011

В пользовательском UITableViewCell классе:

[self.contentView addSubview:but_you]; 

В cellForRowAtIndexPath методе вы можете написать:

[cell.showRewards addTarget:self action:@selector(myAction:) forControlEvents:UIControlEventTouchUpInside];    
cell.showRewards.tag = indexPath.row;
2 голосов
/ 13 сентября 2011

Вы можете назначить indexpath тегу кнопки и получить доступ к вашему методу, например

cell.showRewards.tag = indexPath.row;

-(IBAction)myAction:(id)sender
{
     NSIndexPath *indexPath = [self.tableView indexPathForCell:[sender tag]];
     NSLog(@"Selected row is: %d",indexPath.row);
}
1 голос
/ 13 июля 2014

Если вы хотите indexPath кнопки Определение того, какая кнопка UIB была нажата в UITableView , опишите, как это сделать.

в основном действие кнопки становится:

 - (void)checkButtonTapped:(id)sender
    {
        CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
        NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
        if (indexPath != nil)
        {
         ...
        }
    }
1 голос
/ 03 ноября 2013

В - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath методе напишите код ниже:

  [cell.zoomButton addTarget:self action:@selector(navigateAction:) forControlEvents:UIControlEventTouchUpInside];
cell.zoomButton.tag=indexPath.row;

Затем напишите такой метод:

-(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];
}
1 голос
/ 19 февраля 2013

Мне кажется невероятным, что на самом деле не существует достойного решения этой проблемы.

По какой-то причине я нахожу методы тегирования и «использование визуального расположения ячейки на экране для определенияправильный объект модели », изложенный в других ответах, немного грязный.

Вот два разных подхода к проблеме:

Подкласс UITableViewCell

РешениеЯ пошел с подклассом UITableViewCell

@interface MyCustomCell : UITableViewCell

@property (nonatomic, strong) Model *myModelObject;

@end

При создании ячейки в cellForRowAtIndexPath: вы, вероятно, будете использовать объект модели для заполнения данных ячейки.В этом методе вы можете назначить объект модели ячейке.

А затем в обработчике касания кнопки:

MatchTile *cell = (MatchTile *) sender.superview.superview;

if (cell && cell.myModelObject)
{
    //Use cell.myModelObject
}

Я не на 100% доволен этим решением, если честно.Присоединение объекта домена к такому специализированному компоненту UIKit кажется плохой практикой.

Использование ассоциативных объектов Objective C

Если вы не хотите создавать подкласс для ячейки,еще одна хитрость, которую вы можете использовать, чтобы связать объект модели с ячейкой и получить его позже.

Чтобы извлечь объект модели из ячейки, вам потребуется уникальный ключ для его идентификации.Определите один из них следующим образом:

static char* OBJECT_KEY = "uniqueRetrievalKey"; 

Добавьте следующую строку в метод cellForRowAtIndexPath:, когда вы используете объект модели для заполнения ячейки.Это свяжет ваш объект модели с объектом ячейки.

objc_setAssociatedObject(cell, OBJECT_KEY, myModelObject, OBJC_ASSOCIATION_RETAIN);

И затем, где бы у вас ни была ссылка на эту ячейку, вы можете получить объект модели, используя:

MyModelObject *myModelObject = (MyModelObject *) objc_getAssociatedObject(cell, OBJECT_KEY);

В отражении,хотя я выбрал первое (потому что я уже разделил ячейку на подклассы), второе решение, вероятно, немного чище, так как на ViewController остается ответственность за присоединение и извлечение объекта модели.UITableViewCell не нужно ничего знать об этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...