iOS自定义UITableView实现不同系统下的左滑删除功能详解

前言

在我们的app开发当中,经常会用到UITableView 的左滑删除的功能,通常的话效果如下

但有时候系统现有的功能并不能完全满足我们的开发需求,这样就需要我们在其现有的功能基础上自定义我们所需要的功能了。下图是在项目中自定义的按钮(只是修改了按钮的frame而已)。

然后我就总结了一下根据不同的需求自定义不同的按钮。

一、系统默认左滑删除按钮

如果你对左滑删除按钮的要求不高,仅仅只是实现UITableView上cell的左滑删除功能,那在UITableView的代理方法中添加以下两种方法便可实现需求:

//使用系统默认的删除按钮
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
 if (editingStyle == UITableViewCellEditingStyleDelete){

 }
}
//自定义系统默认的删除按钮文字
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
 return @"自定义按钮”;
}

效果如下所示:


系统自带

虽然这样能基本实现功能,但是我们发现右边的按钮和左边的黄色区域的高度并不一样。这是因为右边按钮是和UITableViewCell的高度一致,而左边的黄色区域只是一张图片而已,其高度设置和UITableViewCell的高度并不一致,才会导致这样的布局出现。如果我们想要删除按钮和左边图片一样的高度,那我们就需要自定义删除按钮的高度了。

二、自定义左滑删除按钮

如果我们想要实现不止一个自定义按钮的功能,那我们就需要在UITableView代理方法- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {}中添加我们所需要的多个按钮了。如下是在不同的cell上添加一个或两个左滑按钮:

//自定义多个左滑菜单选项
- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
 UITableViewRowAction *deleteAction;
 deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"删除" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
 [tableView setEditing:NO animated:YES];//退出编辑模式,隐藏左滑菜单
 }];
 if (indexPath.row == 1) {//在不同的cell上添加不同的按钮
 UITableViewRowAction *shareAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"分享" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
  [tableView setEditing:NO animated:YES];//退出编辑模式,隐藏左滑菜单
 }];
 shareAction.backgroundColor = [UIColor blueColor];
 return @[deleteAction,shareAction];
 }
 return @[deleteAction];
}

在上述代理方法中我们就可以实现在cell中添加一个或多个左滑按钮了,根据点击不同的按钮实现不同的响应方法便可。其中[tableView setEditing:NO animated:YES];方法可以在点击按钮之后退出编辑模式并隐藏左滑菜单。但如果我们想要修改按钮的其他属性如标题、背景颜色怎么办?点击进入UITableViewRowAction类中,我们会发现以下属性和方法:

@interface UITableViewRowAction : NSObject <NSCopying>

+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style title:(nullable NSString *)title handler:(void (^)(UITableViewRowAction *action, NSIndexPath *indexPath))handler;

@property (nonatomic, readonly) UITableViewRowActionStyle style;
@property (nonatomic, copy, nullable) NSString *title;
@property (nonatomic, copy, nullable) UIColor *backgroundColor; // default background color is dependent on style
@property (nonatomic, copy, nullable) UIVisualEffect* backgroundEffect;

@end

其中 @property (nonatomic, readonly) UITableViewRowActionStyle style;是指设置所添加按钮父视图的背景颜色以及按钮字体颜色:

typedef NS_ENUM(NSInteger, UITableViewRowActionStyle) {
 UITableViewRowActionStyleDefault = 0,//红底白字
 UITableViewRowActionStyleDestructive = UITableViewRowActionStyleDefault,
 UITableViewRowActionStyleNormal//灰底白字
} NS_ENUM_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;

@property (nonatomic, copy, nullable) UIVisualEffect* backgroundEffect;提供了一个背景模糊效果,有兴趣的可以自行研究一下。

上述的方法和属性只能满足我们的部分需求,如果我们想要改变按钮的大小或者设置带图片的按钮怎么办?那就需要我们在视图中找到我们所要修改的按钮,并设置它的各种属性。由于在iOS8-10和iOS11下自定义按钮处在不同的视图层次中,所以需要我们先了解UITableView上的视图层次。下图为对比:

左iOS10/右iOS11(Xcode9中)

从对比图中可以看出:

(1).iOS10下视图层次为:UITableView -> UITableViewCell -> UITableViewCellDeleteConfirmationView -> _UITableViewCellActionButton,我们所需自定义的按钮视图UITableViewCellDeleteConfirmationView(左图中红框处)是UITableViewCell的子视图。

(2).iOS11下视图层次为:在Xcode 8中编译为: UITableView -> UITableViewWrapperView -> UISwipeActionPullView -> UISwipeActionStandardButton;

在Xcode 9中编译为: UITableView -> UISwipeActionPullView -> UISwipeActionStandardButton。(iOS11中用Xcode 8和Xcode 9中编译有略微的差别),我们所需自定义的按钮视图UISwipeActionPullView(右图中红框处)是UITableView的子视图。

由于不同系统下的视图层次不一样,因此我们在项目中需要根据不同的代码去同时适配iOS8-10和iOS11。
在iOS8-10中( 以下均在Xcode 9中编译):

在该系统下由于我们所需自定义的按钮视图UITableViewCellDeleteConfirmationView是UITableViewCell的子视图,所以我们在自定义UITableViewCell子类中遍历它的subviews即可。代码如下:

- (void)layoutSubviews {
 /**自定义设置iOS8-10系统下的左滑删除按钮大小*/
 for (UIView * subView in self.subviews) {
 if ([subView isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")]) {
  subView.backgroundColor = [UIColor clearColor];//去掉默认红色背景
  //设置按钮frame
  CGRect cRect = subView.frame;
  cRect.origin.y = self.contentView.frame.origin.y + 10;
  cRect.size.height = self.contentView.frame.size.height - 20;
  subView.frame = cRect;
  //自定义按钮的文字大小
  if (subView.subviews.count == 1 && self.indexPath.section == 0) {//表示有一个按钮
  UIButton * deleteButton = subView.subviews[0];
  deleteButton.titleLabel.font = [UIFont systemFontOfSize:20];
  }
  //自定义按钮的图片
  if (subView.subviews.count == 1 && self.indexPath.section == 1) {//表示有一个按钮
  UIButton * deleteButton = subView.subviews[0];
  [deleteButton setImage:[UIImage imageNamed:@"login_btn_message"] forState:UIControlStateNormal];
  [deleteButton setTitle:@"" forState:UIControlStateNormal];
  }
  //自定义按钮的文字图片
  if (subView.subviews.count >= 2 && self.indexPath.section == 0) {//表示有两个按钮
  UIButton * deleteButton = subView.subviews[1];
  UIButton * shareButton = subView.subviews[0];
  [deleteButton setTitle:@"" forState:UIControlStateNormal];
  [shareButton setTitle:@"" forState:UIControlStateNormal];
  [self setUpDeleteButton:deleteButton];
  [self setUpShareButton:shareButton];
  }
 }
 }
}

在iOS11中:

在该系统下由于我们所需自定义的按钮视图UISwipeActionPullView是UITableView的子视图,所以我们可以在控制器中自定义UITableView子类中遍历它的subviews即可(以下方法是写在UITableView的代理方法- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath中的,该代理方法每次会在开始左滑按钮前调用)。代码如下:

/**自定义设置iOS11系统下的左滑删除按钮大小*/
//开始编辑左滑删除
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath {
 NSInteger section = indexPath.section;
 if (@available(iOS 11.0, *)) {
  for (UIView * subView in self.customTableView.subviews) {
   if ([subView isKindOfClass:NSClassFromString(@"UISwipeActionPullView")]) {
    subView.backgroundColor = [UIColor clearColor];//如果自定义只有一个按钮就要去掉按钮默认红色背景
    //设置按钮frame
    for (UIView * sonView in subView.subviews) {
     if ([sonView isKindOfClass:NSClassFromString(@"UISwipeActionStandardButton")]) {
      CGRect cRect = sonView.frame;
      cRect.origin.y = sonView.frame.origin.y + 10;
      cRect.size.height = sonView.frame.size.height - 20;
      sonView.frame = cRect;
     }
    }
    //自定义按钮的文字大小
    if (subView.subviews.count == 1 && section == 0) {//表示有一个按钮
     UIButton * deleteButton = subView.subviews[0];
     deleteButton.titleLabel.font = [UIFont systemFontOfSize:20];
    }
    //自定义按钮的图片
    if (subView.subviews.count == 1 && section == 1) {//表示有一个按钮
     UIButton * deleteButton = subView.subviews[0];
     [deleteButton setImage:[UIImage imageNamed:@"login_btn_message"] forState:UIControlStateNormal];;
    }
    //自定义按钮的文字图片
    if (subView.subviews.count >= 2 && section == 0) {//表示有两个按钮
     UIButton * deleteButton = subView.subviews[1];
     UIButton * shareButton = subView.subviews[0];
     [self setUpDeleteButton:deleteButton];
     [self setUpShareButton:shareButton];
    }
   }
  }
 }
}

如果我们想在左滑删除结束后实现一些功能,我们可以在UITableView中实现以下代理方法:

//结束编辑左滑删除
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath {

}
如果我们想分别设置UITableViewCell是否需要实现左滑功能,可以在下面代理方法中实现:

//判断是否显示左滑删除
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
 return YES;
}

在不同系统下分别添加以上代码即可实现我们所需要的自定义左滑删除按钮,效果图如下:

以上是我总结整理的在不同系统下的自定义UITableView左滑删除功能。

如有不足之处,欢迎指正交流,Demo地址:左滑删除 (本地下载)

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • iOS中UITableView Cell实现自定义单选功能

    今天分享下cell的单选,自定义的,不是下图这种网上找到的打对勾的,我搜了好久,基本上都是打对勾的文章,就决定自己写一篇.基本上自己的app都会有一个风格吧,咱也不能一直用打对勾的方式去做(看起来是不是很low). 我们要实现的是下面的这种形式.瞬间好看了很多,高大上了很多是吧. 具体我来给大家介绍一下.我这种方法有可能不是很好,有大神来,欢迎多多交流. 首先在你自定义的cell里面加入一个UIImageView,因为你肯定要有选择和未选择两张图片的吧,所以这个UIImageView来切换图片.

  • 实例讲解iOS应用开发中使用UITableView创建自定义表格

    一.带索引目录的表视图 1.效果图 2.数据源 本想获取通讯录中得名字,但为了用模拟器调试方便,就写死了数据,所以也只写了部分字母,总之有那么点意思就成 复制代码 代码如下: @interface ViewController ()<UITableViewDataSource,UITableViewDelegate> {     NSArray *sectionTitles; // 每个分区的标题     NSArray *contentsArray; // 每行的内容 } /** @brie

  • ios UITableView 自定义右滑删除的实现代码

    公司有个奇葩需求.删除按钮带点圆角 不止如此,还有cell之间有间隔,cell圆角,cell左右有间隔.如下图!!!!! 内心奔溃的我想了想了很多方法.(获取系统自带按钮改圆角也试过,自定义手势也试过)最后决定全部自定义.个人感觉这样最合适.下面是效果图 今天有时间,稍微说下实现方式: 这个项目工程只是提供一种思路,应对场景是 需要自定义左滑删除按钮的样式. 因为项目本身并不是修改系统的左滑删除,而是自定义实现,所以任何样式都算使用. 下面先说下项目的结构类型 最底下自然是uitableview

  • 详解ios中自定义cell,自定义UITableViewCell

    通过继承UITableViewCell来自定义cell 1.创建一个空的项目.命名: 2.创建一个UITableViewController 并且同时创建xib: 3.设置AppDelegate.m中window的根控制器为刚刚创建的TableViewController: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { s

  • 全面解析iOS应用中自定义UITableViewCell的方法

    有时候我们需要自己定义UITableViewCell的风格,其实就是向行中添加子视图.添加子视图的方法主要有两种:使用代码以及从.xib文件加载.当然后一种方法比较直观. 一.基本用法 我们这次要自定义一个Cell,使得它像QQ好友列表的一行一样:左边是一张图片,图片的右边是三行标签: 当然,我们不会搞得这么复杂,只是有点意思就行. 1.运行Xcode 4.2,新建一个Single View Application,名称为Custom Cell: 2.将图片资源导入到工程.为此,我找了14张50

  • iOS App开发中使用及自定义UITableViewCell的教程

    UITableView用来以表格的形式显示数据.关于UITableView,我们应该注意: (1)UITableView用来显示表格的可见部分,UITableViewCell用来显示表格的一行. (2)UITableView并不负责存储表格中的数据,而是仅仅存储足够的数据使得可以画出当前可见部分. (3)UITableView从UITableViewDelegate协议获取配置信息,从UITableViewDataSource协议获得数据信息. (4)所有的UITableView实现时实际上只有

  • iOS开发之UITableView左滑删除等自定义功能

    前言 相信每位iOS开发者都知道UITableView的左滑删除功能非常的炫酷,有时候左滑需要的功能不止只有删除一个,有时候会有顶置之类的别的功能,这时候就需要我们自己定制左滑 示例代码 -(NSArray<UITableViewRowAction*>*)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewRowAction *rowActio

  • iOS应用中UITableView左滑自定义选项及批量删除的实现

    实现UITableView左滑自定义选项 当UITableView进入编辑模式,在进行左滑操作的cell的右边,默认会出现Delete按钮,如何自定义左滑出现的按钮呢? 只需要实现UITableView下面的这个代理方法. 复制代码 代码如下: - (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath

  • iOS自定义UITableView实现不同系统下的左滑删除功能详解

    前言 在我们的app开发当中,经常会用到UITableView 的左滑删除的功能,通常的话效果如下 但有时候系统现有的功能并不能完全满足我们的开发需求,这样就需要我们在其现有的功能基础上自定义我们所需要的功能了.下图是在项目中自定义的按钮(只是修改了按钮的frame而已). 然后我就总结了一下根据不同的需求自定义不同的按钮. 一.系统默认左滑删除按钮 如果你对左滑删除按钮的要求不高,仅仅只是实现UITableView上cell的左滑删除功能,那在UITableView的代理方法中添加以下两种方法

  • Linux 系统下安装JDK1.8的教程详解

    一,安装前的清理工作 rpm -qa | grep jdk rpm -qa | grep gcj yum -y remove java-xxx-xxx 二 , 在线下载JDK 命令: wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u131-b1

  • Android使用PullToRefresh完成ListView下拉刷新和左滑删除功能

    ListView下刷新刷功能相信从事Android开发的猿友们并不陌生,包括现在Google亲儿子SwipeRefreshLayout实现效果在一些APP上也能看见(不过个人不喜欢官方的刷新效果).本文就带领一些刚入门android的朋友或者一起爱分享的朋友来简单的实现ListView的下拉刷新和左滑删除效果. 一.本文主要内容: 使用PullToRefresh完成ListView下拉.上拉刷新: 扩展PullToRefresh完美的实现ListView左滑删除效果: 注意:本文中的PullTo

  • iOS开发之tableView实现左滑删除功能

    前言 这几天要实现左划删除的功能,发现网上很多帖子大多出自一人之手,然后都是 copy 的文章,其实都没有那么复杂,只实现一个代理方法就可以了 方法如下 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITa

  • mac系统下Redis安装和使用步骤详解

    前言 本篇文章主要讲述了Mac下Redis的安装和使用的经验,并将python如何操作Redis做了简单介绍. 1. redis 安装 和启动 1.1 用brew安装 1.查看系统是否已经安装了Redis brew info redis 这个命令会展示此系统下的redis信息,如果没有安装,会展示not install 2.输入命令安装Redis brew install redis 可能需要等一会,系统下载完redis的包,会自动进行安装 3.启动redis brew services sta

  • Windows系统下安装MongoDB与Robomongo环境详解

    前言 先到MongoDB官网下载安装包:https://www.mongodb.com/download-center#community我是win7 64位环境,下载默认的那个即可. 在Robomongo官网下载安装包:https://robomongo.org/download 全都是免费的. 安装mongodb: 根据你的系统下载 32 位或 64 位的 .msi 文件,下载后双击该文件,按操作提示安装即可. 安装过程中,你可以通过点击 "Custom(自定义)" 按钮来设置你的

  • Linux系统下virtuoso数据库安装与使用详解

    最近在调研关联数据的一些东西,需要用到rdf数据库,所以接触了virtuoso数据库.安装的坑其实并不多,之前在windows 10上安过一次.这次在ubuntu 18.04上安装一下,其他的linux发行版安装的流程也差不多. virtuoso数据库的下载与使用 开源版本的virtuoso数据库可以在sourceforge下载.我用的是7.25版本.建议下载已经编译好的generic版本(下载图中标红色的那个),需要编译的那个版本我遇到了openssl版本不支持的问题. 下载完毕后将其解压到/

  • iOS 自定义返回按钮保留系统滑动返回功能

    先给大家展示下效果图:  1.简介 使用苹果手机,最喜欢的就是用它的滑动返回.作为一个开发者,我们在编写很多页面的时候,总是会因为这样那样的原因使得系统的滑动返回不可用.使用导航栏push出一个控制器,我们在控制器中自定义了一个返回按钮.这样系统默认的滑动返回手势效果就没有了. 2.解决方法 [1]从A这个控制器push到B这个控制器,我们想要自定义B的返回按钮,我们可以在A中设置 self.navigationItem.backBarButtonItem = [[UIBarButtonItem

  • iOS开发retina屏幕下的点与像素关系详解

    目录 引言 I iOS中点与像素有什么关系? II 图片使用的相关注意事项 2.1 推荐使用png格式 2.2 关于图像的实例化 2.3 动画结束之后清除帧动画数组 III 设置状态栏字体颜色 3.1 方式一 3.2 方式二 see also 引言 提交app store的时候 需要一张1024*1024的 如果不设置这两种的尺寸启动页的话,在4英寸.3.5英寸的设备上展示不了启动页,app 的高度也默认都是矮的960px.** 注意@3x 提供给开发的px 为12422208 ,但真实的px

随机推荐