UITableViewCell左滑button的定制
2015-11-24 15:28
381 查看
如果你重写了tableView: commitEditingStyle: forRowAtIndexPath:函数,那么UITableViewCell在非编辑状态从右向左侧滑,右边会出现红色的“删除”按钮。但如何像微信一样定制button呢?
UITableViewCell
UITableViewCellScrollView
UITableViewCellDeleteConfirmationView
UITableViewCellDeleteConfirmationButton
UITableViewCellContentView
UITableViewCellSeparatorView
找到了这个DeleteConfirmationButton,我们只需要把它替换成我们自己的buttonMenu就行了。
但是从iOS7.1开始,cell为editing状态时DeleteConfirmationButton才存在。为了找到最合适的替换原来DeleteConfirmationButton的timing,进行了诸多尝试:
scrollViewWillBeginDragging_
scrollViewDidScroll_
updateConstraints
updateNavBarButtons
tableView_didEndEditingRowAtIndexPath_
tableView_willBeginEditingRowAtIndexPath_
tableView_commitEditingStyle_forRowAtIndexPath_
UITableViewCellScrollView_addSubview_
UITableViewCellScrollView_scrollViewDidScroll_
UITableViewCellScrollView_setContentOffset_
还有一个名字长得特别像能work的函数scrollViewWillEndDragging_withVelocity_targetContentOffset_,但当在它里面替换button时,我们会看到cell左移时原来的系统deletebutton,在释放cell的瞬间变成我们设置的buttonMenu。
最后能够实现预期效果的是UITableViewCellScrollView_setContentOffset_,当然我们不能在这个函数里面直接替换DeleteConfirmationButton而不做任何判断,因为它会在cell scroll时调用N次,而我们只需要做一次替换DeleteConfirmationButton的操作。
大致的实现逻辑如下:
(其中DView代表UITableViewCellDeleteConfirmationView,DButton代表UITableViewCellDeleteConfirmationButton)
(1) 在UITableViewCellScrollView_setContentOffset_中
若整个table为编辑状态,则不做处理
否则:从Cell的subviews中按照层次关系提取出DView和DButton。若DView不存在,则返回;
否则:获取DView的subviews中是否有buttonMenu,若有则表示已经替换过button,并返回;
否则:初始化buttonMenu,把它加到DView中,并修改DView和DButton的width;
(2) 在PHRecentsCell_scrollViewWillEndDragging_withVelocity_targetContentOffset_函数中中根据buttonMenu中所有Button的宽度之和,设置cell scroll停留的位置(如果不设置,cell完成左滑动作后会停留在系统本身的DButton的左边缘位置)。
UITableViewCell
UITableViewCellDeleteConfirmationView
_UITableViewCellActionButton
UITableViewCellContentView
UITableViewLabel
_UITableViewCellSeparatorView
但幸运的是我们不需要像iOS7那样自己写一个buttonMenu替换系统button,因为Apple在iOS8开放了一个API,用于定制cell左滑时的buttons:
函数返回的类型是NSArray,其中包含的是UITableViewRowAction类型的对象,我们可以设置这个对象的title、backgroundColor、handler等:
虽然button的数量没有限制,但由于button的宽度是系统根据button 的 title进行自动的适应,所以如果buttons的累计宽度太大,在cell里会显示不下。建议在编写代码的具体过程中,考虑不同尺寸屏幕上的显示效果。
iOS8以前
在iOS8以前(应该猜到了在iOS8开始后会有更直接的办法,之后会说到),Apple没有提供直接修改button的API,我们必须用很纠结的方法来进行设置。1.cell的subviews结构
先看看iOS7时cell的subviews结构:UITableViewCell
UITableViewCellScrollView
UITableViewCellDeleteConfirmationView
UITableViewCellDeleteConfirmationButton
UITableViewCellContentView
UITableViewCellSeparatorView
找到了这个DeleteConfirmationButton,我们只需要把它替换成我们自己的buttonMenu就行了。
2.实现方法
在iOS7.1之前,DeleteConfirmationButton一直存在,可以重写layoutSubviews,在这个函数内获取DeleteConfirmationButton。但是从iOS7.1开始,cell为editing状态时DeleteConfirmationButton才存在。为了找到最合适的替换原来DeleteConfirmationButton的timing,进行了诸多尝试:
scrollViewWillBeginDragging_
scrollViewDidScroll_
updateConstraints
updateNavBarButtons
tableView_didEndEditingRowAtIndexPath_
tableView_willBeginEditingRowAtIndexPath_
tableView_commitEditingStyle_forRowAtIndexPath_
UITableViewCellScrollView_addSubview_
UITableViewCellScrollView_scrollViewDidScroll_
UITableViewCellScrollView_setContentOffset_
还有一个名字长得特别像能work的函数scrollViewWillEndDragging_withVelocity_targetContentOffset_,但当在它里面替换button时,我们会看到cell左移时原来的系统deletebutton,在释放cell的瞬间变成我们设置的buttonMenu。
最后能够实现预期效果的是UITableViewCellScrollView_setContentOffset_,当然我们不能在这个函数里面直接替换DeleteConfirmationButton而不做任何判断,因为它会在cell scroll时调用N次,而我们只需要做一次替换DeleteConfirmationButton的操作。
大致的实现逻辑如下:
(其中DView代表UITableViewCellDeleteConfirmationView,DButton代表UITableViewCellDeleteConfirmationButton)
(1) 在UITableViewCellScrollView_setContentOffset_中
若整个table为编辑状态,则不做处理
否则:从Cell的subviews中按照层次关系提取出DView和DButton。若DView不存在,则返回;
否则:获取DView的subviews中是否有buttonMenu,若有则表示已经替换过button,并返回;
否则:初始化buttonMenu,把它加到DView中,并修改DView和DButton的width;
(2) 在PHRecentsCell_scrollViewWillEndDragging_withVelocity_targetContentOffset_函数中中根据buttonMenu中所有Button的宽度之和,设置cell scroll停留的位置(如果不设置,cell完成左滑动作后会停留在系统本身的DButton的左边缘位置)。
iOS8开始
刚提到了iOS7和7.1cell中DeleteConfirmationButton的出现时机是不一样的,而到了iOS8,cell连层级结构都变了╮(╯_╰)╭。UITableViewCell
UITableViewCellDeleteConfirmationView
_UITableViewCellActionButton
UITableViewCellContentView
UITableViewLabel
_UITableViewCellSeparatorView
但幸运的是我们不需要像iOS7那样自己写一个buttonMenu替换系统button,因为Apple在iOS8开放了一个API,用于定制cell左滑时的buttons:
- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath;
函数返回的类型是NSArray,其中包含的是UITableViewRowAction类型的对象,我们可以设置这个对象的title、backgroundColor、handler等:
UITableViewRowAction *action = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"删除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) { //button按下的处理 }]; action.backgroundColor = [UIColor orangeColor];
虽然button的数量没有限制,但由于button的宽度是系统根据button 的 title进行自动的适应,所以如果buttons的累计宽度太大,在cell里会显示不下。建议在编写代码的具体过程中,考虑不同尺寸屏幕上的显示效果。
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 讲解iOS开发中基本的定位功能实现
- js判断客户端是iOS还是Android等移动终端的方法
- IOS开发环境windows化攻略
- 浅析iOS应用开发中线程间的通信与线程安全问题
- 检测iOS设备是否越狱的方法
- .net平台推送ios消息的实现方法
- 探讨Android与iOS,我们将何去何从?
- Android、iOS和Windows Phone中的推送技术详解
- IOS 改变键盘颜色代码
- 举例详解iOS开发过程中的沙盒机制与文件
- Android和IOS的浏览器中检测是否安装某个客户端的方法
- 分享一个iOS下实现基本绘画板功能的简单方法
- javascript实现阻止iOS APP中的链接打开Safari浏览器