在实际开发工作中,我们经常会在自定义的Cell中布局一些按钮,并且很多时候我们会在点击这个按钮的时候使我们的UItableviewController跳转到下一界面,有的可能还要传值。那么如何使我们的控制器能够获知我们按下了cell的按钮呢?毫无疑问,这是个代理模式的典型应用场景。
首先我们先得定义一个cell。.h文件如下:
- @protocol MycellDelegate <NSObject>
-
- @optional
- -(void)didClickButton:(UIButton *)button;
-
- @end
-
- @interface Mycell : UITableViewCell
-
- +(instancetype)cellWithtableView:(UITableView *)tableview;
-
- @property(nonatomic,strong)DateModel *model;
-
- @property(nonatomic,weak) id<MycellDelegate> delegate;
.m文件如下:
- #import "Mycell.h"
-
- @interface Mycell()
-
- @property(nonatomic,strong)UIButton *button;
-
- @end
-
- @implementation Mycell
-
- +(instancetype)cellWithtableView:(UITableView *)tableview
- {
- static NSString *ID = @"cell";
- Mycell *cell = [tableview dequeueReusableCellWithIdentifier:ID];
- if(!cell)
- {
- cell = [[Mycell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- cell.textLabel.font = [UIFont systemFontOfSize:13.0];
- }
- return cell;
-
- }
-
-
-
- -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
- {
- self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
- if(self)
- {
- self.button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, self.frame.size.height)];
- [self.button setTitle:@"我是按钮点我" forState:UIControlStateNormal];
- [self.button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
- self.button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
- self.button.titleLabel.font = [UIFont systemFontOfSize:12.0];
- [self.contentView addSubview:self.button];
- [self.button addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
- }
- return self;
- }
-
-
-
- -(void)setModel:(DateModel *)model
- {
- self.textLabel.text = [NSString stringWithFormat:@"日期:%@、信息:%@",model.date,model.message];
-
- }
-
- #pragma mark - 按钮点击事件,通过代理模式响应
- -(void)btnClick:(UIButton *)btn
- {
- [self.delegate didClickButton:btn];
- }
-
- @end
上述代码定义了一个代理,当按下按钮时,代理响应。
现在回到UItableviewController,代码如下:
- -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- Mycell *cell = [Mycell cellWithtableView:tableView];
- cell.model = self.Array[indexPath.row];
- cell.delegate = self;
- return cell;
- }
别忘了.delegate = self哦!代理执行的代码如下:
- #pragma mark - 代理事件
-
- -(void)didClickButton:(UIButton *)button
- {
- Mycell *cell = (Mycell *)button.superview.superview;
- NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
- MessageController *vc = [[MessageController alloc]init];
- DateModel *model = self.Array[indexPath.row];
- vc.message = [NSString stringWithFormat:@"行号:第%ld行,日期:%@、信息:%@",(long)indexPath.row,model.date,model.message];
- [self.navigationController pushViewController:vc animated:YES];
- }
当我们的cell中按钮点击后,将会自动跳到这个代理方法中,我们获取到按钮所在的cell,通过indexPathforCel这个方法(系统API)可以获取到cell的行数,并拿到数据源,此时想要传值给下一个界面就变的非常简单。
特别提醒:
当同一个工厂方法创建多行cell中的button时,要分别做处理的话需要分别对应cell的button添加tag,设置代理事件时,通过tag值来区分