2011-09-13 63 views
9

我一直在寻找解决方案,但似乎无法找到适合我的解决方案。我有一个自定义的单元格,里面有一个按钮。我的问题是如何将indexPath传递给操作方法?自定义UITableViewCell按钮操作?

现在我做

[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); 
} 

任何提示吗?谢谢。

+0

您使用的是didSelectRow:方法? – tipycalFlow

回答

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。您们好后此去......

瞧,你不只是indexPath而且在点击发生的实际单元格。若要从数据源获取的实际数据(假设其NSArray的),你可以做 -

[datasource objectAtIndex:[indexPath row]];

+0

我正要建议NSIndexPath * indexPath = [tableView indexPathForRowAtPoint:[[[event touchesForView:button] anyObject] locationInView:tableView]];但这更清洁,谢谢! – phi

+3

嗯,我错过了什么吗?其实是[sender locationInView:self.tableView];为你工作? – phi

+0

不适合我。我得到[UIButton locationInView:]:无法识别的选择器发送到instanc。 – djskinner

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); 
} 
3

试试这一个。

cell.showRewards.tag=indextPath.row 

在cellforrowatindexpath tableview方法中实现此操作。

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

您设置的按钮标记值= indexpath,并检查它的功能,如果标记值是这个做什么ü想

7
cell.showRewards.tag = indexPath.row; 

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

这个工程,使用,而不是UIButton locationInView – JulianB

2

在定制UITableViewCell类:

[self.contentView addSubview:but_you]; 

cellForRowAtIndexPath方法,你可以写:

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

[sender superview]访问不MyCustomCell,但它是contentView。 读UITableViewCell类参考:

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

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

讨论: 一个UITableViewCell对象的内容视图是由该单元所显示的内容的缺省上海华。如果您想通过简单地添加附加视图来自定义单元格,则应该将它们添加到内容视图中,以便在单元格进入和退出编辑模式时适当定位它们。

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

1

我觉得难以置信的是,没有真正的体面解决方案。

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

这里有两种不同的方法的问题:

子类的UITableViewCell

cellForRowAtIndexPath:有是子类的UITableViewCell

@interface MyCustomCell : UITableViewCell 

@property (nonatomic, strong) Model *myModelObject; 

@end 

在创建细胞去的解决方案,您是可能会使用模型对象来填充单元格数据。在这种方法中,您可以将模型对象分配给单元格。

然后在按钮自来水处理:

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不需要知道任何事情。

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

这实际上是一个很好的类别,它也可以处理iOS 7和 manderson

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]; 
} 
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) 
     { 
     ... 
     } 
    } 
0

这里是 “最简单的方式” 来做到这一点(测试IOS11):

NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint 
[[[sender superview] superview] center]];