它是github上面的一个可自定侧滑删除,更多按钮的三方库,支持iOS7以及以上。地址:https://github.com/scheinem/MSCMoreOptionTableViewCell。大致效果如下:
如果你的tableView的delegate实现了tableView:editActionsForRowAtIndexPath:方法,可能会导致这个库无法使用。
如果需要使用删除按钮的功能跟使用原生的方法一样实现下列两个方法即可:
-tableView:editingStyleForRowAtIndexPath:
-tableView:commitEditingStyle:forRowAtIndexPath:
我们能够做的就是添加一个More按钮,定制其样式,事件;调整Delete按钮的样式。
因为UIKit中很多控件的一些部分控件是没有开放接口的,遍历cell的所有子视图并没有找到一个私有的删除按钮这样一个控件。我们来看下,UITableViewCell的子视图层级结构如下图:
上图中的UITableViewCellDeleteConfirmationView(后面简述为confirmationView)只有在cell被侧滑的时候才会存在(补充,图中有两个UITableViewCellSeparatorView是因为tableView的style是UITableViewStyleGrouped)。
MSCMoreOptionTableViewCell.h文件下:
MSCMoreOptionTableViewCell.m文件下:
由于iOS 7 以及 iOS 8(或以上) UITableViewCell的实现方式不同,所以为了兼容两个不同的版本的实现有两个不同的处理,但是总体的思路是一致的,即confirmationView被添加到父视图上的时候,去配置confirmationView上的Delete,More按钮。
在iOS7上,cell侧滑时,confirmationView被添加到UITableViewCellScrollView(后面简述为cellScrollView)上。cell在初始化的时候调用setupObserving,寻找到cellScrollView添加监听。
监听触发时调用:- (void)observeValueForKeyPath:ofObject:change:context:方法。其中将遍历cellScrollView的子视图找到confirmationView,继续遍历出UITableViewDeleteConfirmationButton(后面简述为DeleteButton),然后对DeleteButton和confirmationView的样式进行配置。
图中
-configureMoreOptionButtonForDeleteConfirmationView:withDeleteConfirmationButton:
方法里面主要是根据代理方法去从delegate获取来设定MoreOptionButton 的title、titleColor、backgroundColor、miniMumWidth、edgeInsets;设定DelelteButton的backgroundColor,titleColor,edgeInsets;根据self.configurationBlock 设定MoreOptionButton,DeleteButton 的宽度;执行self.configurationBlock的设置配置MoreOptionButton,DeleteButton。根据MoreOptionButton,Deletebutton的frame来重新设定confirmationView的frame。
self.configurationBlock参数中包含了DeleteButton,MoreOptionButton参数,我们block可以给着两个button添加子视图,设定title,titleColor等。self.configurationBlock的执行顺序在delegate对Deletebutton,MoreOptionButton配置之后,所以也会生效。
MoreOptionButton的创建:只是在delegate获取到的MoreOptionButton的title存在或者self.configurationBlock存在时才会被创建,MoreOptionButton被添加作为confirmationView的子视图。
以上就是iOS7系统下confirmationView被添加到cellScrollView上的整个过程。
当confirmationView被移除的时候MSCMoreOptionTableViewCell的内部变量MoreOptionButton和cellScrollView被置为nil。
在iOS 8 下,confirmView是被insert到cell上。于是我们重写insertSubview:atIndex:对confirmationView及其子视图进行配置,重写willRemoveSubview:当confirmationView移除的时候将MoreOptionButton值为nil。根据UITableViewCell的子视图层级结构图知道DeleteButton类型为_UITableViewCellActionButton,我们仍然先从cell的子视图中找到confirmationView,再从confirmationView的子视图找到Deletebutton。接下来调用
- configureMoreOptionButtonForDeleteConfirmationView:withDeleteConfirmationButton:
和上述iOS 7 所执行的操作相同。唯一不同的是在这之后需要设置contentSize:
上述的view即遍历找到的confirmationView,我们看到在执行了 configureMoreOptionButtonXXXX之后,confirmationView重新执行了一遍初始化方法专门来去设置contentSize,why?而且执行初始化方法并没有生成新的对象,所以之前添加到上面的MoreOptionButton仍然在confirmationView上面,这是一个令人困惑的地方。
总结
1.了解到一些UITableViewCell的内部细节。
2.由cell获取到tableView的方式->不断遍历cell的superView,以及其他类似的一些用法。
3.在调用UIKit的private api时可用字符串的拼接,或者前缀后缀的方式以躲避苹果的审核检查。
4.通过监听view.layer的sublayers来检测子视图的添加和移除,等等。
5.iOS 7 下用scrollView来实现侧滑手势,iOS 8 使用什么来实现这个侧滑手势的呢?