自定义UITableViewCell按钮动作?

时间:2011-09-13 08:50:07

标签: iphone objective-c ios uitableview uibutton

我一直在四处寻找解决方案,但似乎找不到适合我的解决方案。我有一个内置按钮的自定义单元格。我的问题是如何将indexPath传递给action方法?

现在我正在做

 [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 个答案:

答案 0 :(得分:8)

只想添加我认为最好的解决方案: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

答案 1 :(得分:7)

cell.showRewards.tag = indexPath.row;

-(IBAction)myAction:(id)sender
{
UIButton *btn = (UIButton *)sender;
int indexrow = btn.tag;
NSLog(@"Selected row is: %d",indexrow);
}

答案 2 :(得分:5)

虽然我觉得为按钮设置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可以使用方法indexPathForRowAtPoint:为您提供indexPath。你很高兴去追寻......

Voila,您不仅有indexPath,还有点击发生的实际单元格。要从数据源获取实际数据(假设其NSArray),您可以执行 -

[datasource objectAtIndex:[indexPath row]];

答案 3 :(得分:3)

试试这个。

cell.showRewards.tag=indextPath.row

在cellforrowatindexpath tableview的方法中实现它。

-(IBAction)myAction:(id)sender{
UIButton* btn=(UIButton*)sender;
NSLog(@"Selected row is: %d",btn.tag);
}

答案 4 :(得分:3)

您设置了按钮标记值= indexpath并在函数中检查它是否符号是这样做

答案 5 :(得分:2)

您可以将indexpath分配给按钮标记并在方法中进行访问,如

cell.showRewards.tag = indexPath.row;

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

答案 6 :(得分:2)

在自定义UITableViewCell课程中:

[self.contentView addSubview:but_you]; 

cellForRowAtIndexPath方法中,您可以写:

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

答案 7 :(得分:1)

[sender superview]中,您不是MyCustomCell,而是contentView。 阅读UITableViewCell班级参考:

contentView 返回单元格对象的内容视图。 (只读)

@property(nonatomic, readonly, retain) UIView *contentView

讨论: UITableViewCell对象的内容视图是单元格显示的内容的默认超级视图。如果您想通过简单地添加其他视图来自定义单元格,则应将它们添加到内容视图中,以便在单元格进入和退出编辑模式时将它们正确定位。

修改代码的最简单方法是使用[[sender superview] superview]。 但是如果稍后修改单元格并在另一个视图中插入按钮,这将停止工作。 contentView出现在iPhoneOS 2.0中。类似的未来修改将影响您的代码。这就是我不建议用这种方式的原因。

答案 8 :(得分:1)

我觉得不可思议的是,对此没有真正合适的解决方案。

无论出于何种原因,我发现标记方法和'使用屏幕上单元格的可视位置来识别正确的模型对象'在其他答案中概述了一点点。

以下是解决该问题的两种不同方法:

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

说实话,我对这个解决方案并不是百分之百。将域对象附加到这样一个专门的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不需要了解它。

答案 9 :(得分:1)

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

答案 10 :(得分:1)

如果您希望按钮Detecting which UIButton was pressed in a UITableView的indexPath描述如何。

基本上按钮动作变为:

 - (void)checkButtonTapped:(id)sender
    {
        CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
        NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
        if (indexPath != nil)
        {
         ...
        }
    }

答案 11 :(得分:0)

这是“最简单的方法”(在IOS11上测试):

podEventRow = soup.find_all('div', class_="podEventRow")
for row in podEventRow:
    team_name = row.find('div', class_="ippg-Market_CompetitorName").get_text(strip=True).replace('\t\r\n', '')
    market_odds_raw = row.find_all('div', class_="ippg-Market_Topic")
    market_odds = ''
    for odd in market_odds_raw:
        market_odds += ' - ' + odd.get_text(strip=True).replace('\t\r\n', '')
    print(team_name + market_odds)