程序员

自定义TableViewCell上的按钮响应方法介绍 进来看看吧

一、 前言

在开发过程中,系统自带的cell有时候满足不了需求而不得不使用自定义的cell。有时候,自定义cell上会有各种各样的按钮,当点击按钮的时候是需要去处理事件。下面来记录一下各种处理的方法并大致说一下利弊。

二、 效果图

由于我比较懒惰,就已我现在在练习的项目举例子好了。
(ps:这个花田小憩项目是我在简书上看到的,但是作者是用swift写的,觉得界面很好看,就试着用oc写了起来)

demo.gif

大致说一下要实现的,就是点击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设计模式。随着经验的增多,胆子的增大,就去试着其他的奇葩方式了。总之,没有最高级的方法,只有最贴合项目的方法。