[英]Custom UITableViewCell button action?
我一直在寻找解决方案,但似乎找不到适合我的解决方案。 我有一个内置按钮的自定义单元格。 我的问题是如何将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);
}
有小费吗? 谢谢。
只想添加我认为最好的解决方案: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
cell.showRewards.tag = indexPath.row;
-(IBAction)myAction:(id)sender
{
UIButton *btn = (UIButton *)sender;
int indexrow = btn.tag;
NSLog(@"Selected row is: %d",indexrow);
}
虽然我觉得为按钮设置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:
为您提供indexPathForRowAtPoint:
。 你很高兴去追寻......
瞧,你不仅有indexPath
,还有点击发生的实际单元格。 要从数据源获取实际数据(假设其NSArray),您可以 -
[datasource objectAtIndex:[indexPath row]];
试试这个吧。
cell.showRewards.tag=indextPath.row
在cellforrowatindexpath tableview的方法中实现它。
-(IBAction)myAction:(id)sender{
UIButton* btn=(UIButton*)sender;
NSLog(@"Selected row is: %d",btn.tag);
}
您设置按钮标记值= indexpath并在函数中检查它,如果标记值是这样做你想要的
您可以将indexpath分配给按钮标记,并在方法中进行访问
cell.showRewards.tag = indexPath.row;
-(IBAction)myAction:(id)sender
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:[sender tag]];
NSLog(@"Selected row is: %d",indexPath.row);
}
在自定义UITableViewCell
类中:
[self.contentView addSubview:but_you];
在cellForRowAtIndexPath
方法中,您可以编写:
[cell.showRewards addTarget:self action:@selector(myAction:) forControlEvents:UIControlEventTouchUpInside];
cell.showRewards.tag = indexPath.row;
我觉得不可思议的是,没有真正合适的解决方案。
无论出于何种原因,我发现标记方法和'使用屏幕上单元格的可视位置来识别正确的模型对象'在其他答案中概述有点脏。
以下是该问题的两种不同方法:
子类化UITableViewCell
我使用的解决方案是子类UITableViewCell
@interface MyCustomCell : UITableViewCell
@property (nonatomic, strong) Model *myModelObject;
@end
在cellForRowAtIndexPath:
创建单元格时cellForRowAtIndexPath:
您可能正在使用模型对象来填充单元格数据。 在此方法中,您可以将模型对象分配给单元格。
然后在按钮点击处理程序中:
MatchTile *cell = (MatchTile *) sender.superview.superview;
if (cell && cell.myModelObject)
{
//Use cell.myModelObject
}
说实话,我对这个解决方案并不是百分之百满意。 将域对象附加到这样一个专门的UIKit组件感觉就像是不好的做法。
使用Objective-C关联对象
如果您不想对单元格进行子类化,则可以使用另一些技巧将模型对象与单元格关联并稍后检索它。
要从单元格中检索模型对象,您需要一个唯一的键来标识它。 像这样定义一个:
static char* OBJECT_KEY = "uniqueRetrievalKey";
在使用模型对象填充单元格时, cellForRowAtIndexPath:
下行添加到cellForRowAtIndexPath:
方法。 这会将模型对象与单元格对象相关联。
objc_setAssociatedObject(cell, OBJECT_KEY, myModelObject, OBJC_ASSOCIATION_RETAIN);
然后,只要您有对该单元格的引用,就可以使用以下方法检索模型对象:
MyModelObject *myModelObject = (MyModelObject *) objc_getAssociatedObject(cell, OBJECT_KEY);
在反思中,虽然我选择了第一个(因为我已经将子类化为子类),但第二个解决方案可能更清晰,因为它仍然是ViewController的附加和检索模型对象的责任。 UITableViewCell不需要了解它。
在- (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];
}
如果你想要按钮的indexPath 检测在UITableView中按下了哪个UIButton描述了如何。
基本上按钮动作变为:
- (void)checkButtonTapped:(id)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
if (indexPath != nil)
{
...
}
}
在[sender superview]
您不访问MyCustomCell
,但它是contentView
。 阅读UITableViewCell
类参考:
contentView
返回单元格对象的内容视图。 (只读)
@property(nonatomic, readonly, retain) UIView *contentView
讨论: UITableViewCell
对象的内容视图是单元格显示的内容的默认超级视图。 如果要通过简单地添加其他视图来自定义单元格,则应将它们添加到内容视图中,以便在单元格进入和退出编辑模式时将它们正确定位。
修改代码的最简单方法是使用[[sender superview] superview]
。 但是如果稍后修改单元格并在另一个视图中插入按钮,这将停止工作。 contentView出现在iPhoneOS 2.0
。 类似的未来修改将影响您的代码。 这就是我不建议用这种方式的原因。
这是“最简单的方法”(在IOS11上测试):
NSIndexPath *indexPath = [myTable indexPathForRowAtPoint:[[[sender superview] superview] center]];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.