UITableViewCell左滑button的定制

本文介绍了在iOS8以前和以后如何定制UITableViewCell左滑时的删除按钮,包括修改cell的subviews结构,以及利用iOS8提供的API实现自定义操作。

如果你重写了tableView: commitEditingStyle: forRowAtIndexPath:函数,那么UITableViewCell在非编辑状态从右向左侧滑,右边会出现红色的“删除”按钮。但如何像微信一样定制button呢?

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里会显示不下。建议在编写代码的具体过程中,考虑不同尺寸屏幕上的显示效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值