使用UITableViewAction自定义UITableView左滑样式(iOS8及以后可用)

首先,举个栗子:微信会话列表,左滑某个会话cell,会有“标为未读”、“删除”两个选项。在我们的日常开发中,也经常会遇到这样的需求,网上也有很多大神写了相关的三方库,但在很多情况下,开发人员只需要这些三方库的一小部分功能,却要引入整个三方库,增大项目体积。这里,给大家提供一种系统自带的简单实现方案。

一、左滑仅需要展示单个按钮

左滑后仅需要展示单个按钮,这是一种很简单、试用场景很多的需求,实现以下几个代理即可(要遵循UITableViewDelegate代理,这个不做细节阐述了哈):

- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
  // 文案根据需求自定义即可
  return @"删除";
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
  // UITableViewCellEditingStyleNone 不做任何操作
  // UITableViewCellEditingStyleDelete 删除
  // UITableViewCellEditingStyleInsert 插入
  return UITableViewCellEditingStyleDelete;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
  // 执行你的删除逻辑,完成后删除这个cell
  [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}

实现这三个代理,你可以根据具体的需求情况设置展示文案和对应的逻辑操作,然后左滑展示单个按钮就完成了。

二、左滑后展示多个按钮

在某些场景下,需求希望左滑后能够展示多个按钮供用户选择,这时候上述方法显然无法满足需求。网上有很多的大佬,写了一些库,来帮助实现这样的功能。从iOS8开始,UITableView的UITableViewDelegate中增加了如下方法,可以自定义左滑后显示多个按钮,样式也有多种选择:

- (nullable NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED

这个方法需要返回一个装有UITableViewRowAction的数组(可空),这样就实现了左滑有展示多个按钮的需求了。话不多说,上代码:

- (nullable NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
  NSMutableArray *rowActions = [NSMutableArray array];
  
  UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"删除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
    // 点击后回调,在这里执行相关操作
    NSLog(@"elete action")
  }];
  [rowActions addObject:deleteAction];
  
  UITableViewRowAction *unreadActions = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"标为未读" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
    // 点击后回调,在这里执行相关操作
    NSLog(@"unread action");
  }];
  [rowActions addObject:unreadActions];
  
  return rowActions;
}

完成上述代码后,就实现了微信会话左滑的功能了,同理也可以定制成其他样式(如果部分cell不需要左滑功能,直接返回空数组即可,这也是声明一个可变数组的原因之一)。在实现该代理方法后,以下代理方法就不执行了:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;

在我实现的过程中,发现:如果你选择使用UITableViewRowAction的方式实现左滑,下面这个代理也不需要实现,是否能够左滑,完全由返回的UITableViewRowAction数组来决定,当然,这个方法会执行,但已不起作用。

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;

所以,在实现功能的过程中,要结合实际选择性使用对应的代理方法,尽量不要出现无用代码,保持项目的整洁。

三、UITableViewRowAction

接下来我们说说UITableViewRowAction,它是iOS8开始提供的,拥有一个类方法和四个属性。

+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style title:(nullable NSString *)title handler:(void (^)(UITableViewRowAction *action, NSIndexPath *indexPath))handler;

我们可以通过这个类方法来初始化一个UITableViewRowAction对象,以下style参数的相关信息:

typedef NS_ENUM(NSInteger, UITableViewRowActionStyle) {
    UITableViewRowActionStyleDefault = 0, // 红底白字
    UITableViewRowActionStyleDestructive = UITableViewRowActionStyleDefault,
    UITableViewRowActionStyleNormal // 灰底白字
} NS_ENUM_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;

在你选择style的时候,系统为你提供了对应的背景色,你也可以通过 UITableViewRowAction 的 backgroundColor 属性来自己设置action的背景色。

 

最后,非常感谢您的耐心阅读!如有任何问题或描述不清晰的地方,欢迎在评论区留言,我会仔细阅读并回复!

你可能感兴趣的:(iOS开发)