您的位置:首页 > 产品设计 > UI/UE

UITableViewCell左滑button的定制

2015-11-24 15:28 381 查看
如果你重写了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里会显示不下。建议在编写代码的具体过程中,考虑不同尺寸屏幕上的显示效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios uitableviewcell