一、 前言
在开发过程中,系统自带的cell有时候满足不了需求而不得不使用自定义的cell。有时候,自定义cell上会有各种各样的按钮,当点击按钮的时候是需要去处理事件。下面来记录一下各种处理的方法并大致说一下利弊。
二、 效果图
由于我比较懒惰,就已我现在在练习的项目举例子好了。
(ps:这个花田小憩项目是我在简书上看到的,但是作者是用swift写的,觉得界面很好看,就试着用oc写了起来)
大致说一下要实现的,就是点击cell的头像控件,跳转到另一个视图控制器。
三、 正文
下面说一下处理的几种方法
第一种:
简介
给cell设置target以及action,同时在设置的时候初始化UITapGestureRecognizer。
具体操作
在cell.h文件中声明方法:
- (void)setTarget:(id)target action:(SEL)action;
在.m文件中实现方法
- (void)setTarget:(id)target action:(SEL)action
{
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:target action:action];
[_headView addGestureRecognizer:tap];
}
然后在控制器的tableview的cellForRowAtIndexPath方法里设置:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
YQArticleComplexCell *cell = [YQArticleComplexCell cellWithTableView:tableView];
YQArticleModel *articleModel = self.articleList[indexPath.row];
// 设置target以及action,同时在设置的时候初始化UITapGestureRecognizer
[cell setTarget:self action:@selector(headViewDidClick)];
cell.articleModel = articleModel;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
当然,headViewDidClick这个方法只需在控制器中定义了。
- (void)headViewDidClick
{
// PUSH
}
但是,我push过去后是进入用户详情界面的,至少传过去一个用户id吧,那么弊端就来了,就是传递数据比较麻烦。我目前就想到一种方法:通过tap获取到cell对象,然后再获得cell对象里面的用户对象。代码:
- (void)headViewDidClick:(UIGestureRecognizer *)tap
{
YQArticleComplexCell *cell = (YQArticleComplexCell *)tap.view.superview.superview.superview;
YQLog(@"%@", cell.articleModel.author.userName);
// PUSH
}
可以看到,我用了很多层的superview,直到取到cell对象,这个具体得看你的cell结构的。
总结
这个方法确实有点麻烦,且不同的cell结构就不一样,但是当不需要传递数据的时候,这个方法还是很简单粗暴的。
第二种
简介
给cell设置一个viewController,在cell里面直接push。
具体操作
在cell.h文件中声明方法:
- (void)attachWithViewController:(UIViewController *)viewController;
在.m文件中实现方法:
- (void)attachWithViewController:(UIViewController *)viewController
{
self.viewController = viewController;
}
同时给头像控件添加一个点击手势,并实现手势响应:(这里的响应是在cell里面的)
- (void)headViewDidClick
{
// PUSH
YQUserCenterViewController *userCenter = [[YQUserCenterViewController alloc] init];
userCenter.userID = self.articleModel.author.id;
[self.viewController.navigationController pushViewController:userCenter animated:YES];
}
总结
这个方法确实可以传递数据,而且代码看起来比较简洁,但是缺点就是耦合度比较高,毕竟在view中干一些控制器的方法还是不太合理的。但是实在没什么思绪的时候,还是可以用一下的。
第三种
简介
通过block传递并跳转
具体操作
先定义一个block属性:
typedef void (^headViewClickBlock)(YQArticleModel *articleModel);
@interface YQArticleComplexCell : UITableViewCell
@property (nonatomic, strong) YQArticleModel *articleModel;
@property (nonatomic, copy) headViewClickBlock block;
+ (instancetype)cellWithTableView:(UITableView *)tableView;
@end
在头像视图点击后回调
- (void)headViewDidClick
{
self.block(self.articleModel);
}
最后在控制器的tableview的cellForRowAtIndexPath方法里设置:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (_showType == 0) {
YQArticleComplexCell *cell = [YQArticleComplexCell cellWithTableView:tableView];
YQArticleModel *articleModel = self.articleList[indexPath.row];
cell.block = ^(YQArticleModel *artcleModel){
YQLog(@"%@", articleModel.author.userName);
// PUSH
};
cell.articleModel = articleModel;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
总结
第三个方法用的比较多,但是需要注意block里的循环引用问题。
第四种
简介
通过delegate模式来传递并跳转
具体操作
这个方法较为复杂,但也较为简单,所以不详细说明了。
四、 最后
这些方法都是我亲自用过的,而且使用的顺序是这篇文章介绍的顺序的相反,因为最先接触的就是delegate设计模式。随着经验的增多,胆子的增大,就去试着其他的奇葩方式了。总之,没有最高级的方法,只有最贴合项目的方法。
网友评论