在實際開發工作中,我們經常會在自定義的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值來區分