服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - iOS自定义UITableView实现不同系统下的左滑删除功能详解

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

2021-05-10 13:58wuyukobe IOS

关于左滑删除这块,相信不少朋友都遇到过。下面这篇文章主要给大家介绍了关于iOS如何自定义UITableView实现不同系统下的左滑删除功能的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

前言

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

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

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

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
//使用系统默认的删除按钮
- (void)tableview:(uitableview *)tableview commiteditingstyle:(uitableviewcelleditingstyle)editingstyle forrowatindexpath:(nsindexpath *)indexpath {
 if (editingstyle == uitableviewcelleditingstyledelete){
 
 }
}
//自定义系统默认的删除按钮文字
- (nsstring *)tableview:(uitableview *)tableview titlefordeleteconfirmationbuttonforrowatindexpath:(nsindexpath *)indexpath {
 return @"自定义按钮”;
}

效果如下所示:

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

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

二、自定义左滑删除按钮

如果我们想要实现不止一个自定义按钮的功能,那我们就需要在uitableview代理方法- (nsarray<uitableviewrowaction *> *)tableview:(uitableview *)tableview editactionsforrowatindexpath:(nsindexpath *)indexpath {}中添加我们所需要的多个按钮了。如下是在不同的cell上添加一个或两个左滑按钮:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//自定义多个左滑菜单选项
- (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类中,我们会发现以下属性和方法:

?
1
2
3
4
5
6
7
8
9
10
@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;是指设置所添加按钮父视图的背景颜色以及按钮字体颜色:

?
1
2
3
4
5
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上的视图层次。下图为对比:

iOS自定义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即可。代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
- (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中的,该代理方法每次会在开始左滑按钮前调用)。代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**自定义设置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中实现以下代理方法:

?
1
2
3
4
5
6
7
8
9
10
//结束编辑左滑删除
- (void)tableview:(uitableview *)tableview didendeditingrowatindexpath:(nsindexpath *)indexpath {
 
}
如果我们想分别设置uitableviewcell是否需要实现左滑功能,可以在下面代理方法中实现:
 
//判断是否显示左滑删除
- (bool)tableview:(uitableview *)tableview caneditrowatindexpath:(nsindexpath *)indexpath {
 return yes;
}

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

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

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

如有不足之处,欢迎指正交流,demo地址:左滑删除

总结

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

原文链接:https://www.jianshu.com/p/b258b55e4a5c

延伸 · 阅读

精彩推荐
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17