在UITableView滑动中添加其他按钮

时间:2015-01-09 06:40:13

标签: ios tableview customization swipe

目前我正在使用NSFetchedResultsController来处理表视图。 我想知道有没有办法在滑动操作中添加其他按钮,如删除按钮?

我正在考虑将其子类化。但是在帮助文档中找不到与我的问题相关的内容。

提前致谢。

2 个答案:

答案 0 :(得分:48)

你的头衔有误导性。 NSFetchedResultsController与您的最终目标无关。子类化只会创建超出必要的工作量,您想要查看的是UITableViewRowAction。这非常容易处理。与新UIAlertController类似,如果您已经涉足UIAlertController

,那么您应该对此感到非常满意

UITableViewRowAction的简要概要(直接来自the docs):

  

询问代理以显示响应指定行中的滑动的操作。 (需要)   如果要为其中一个表行提供自定义操作,请使用此方法。当用户在一行中水平滑动时,表格视图会将行内容移到一边以显示您的操作。点击其中一个操作按钮可执行与操作对象一起存储的处理程序块。   如果未实现此方法,则表视图会在用户滑动行时显示标准附件按钮。

开始前的几点说明:

  • Apple在iOS8中实现了这一点:因此请仔细考虑您的部署目标。如果您严格编码i0S8,这是第三方库的快速简便替代方案或创建自定义UITableView编辑样式。如果您的目标是保留iOS7的兼容性,则您的选项受限于此格式。 SIDE NOTE 这不会导致代码出现致命错误,iOS7应用不会崩溃,但自定义操作根本无法显示。
  • 标题之外没有太多自定义
  • 这个的优点是,所有东西都用块来处理

无论如何,要实现自定义UITableViewRowAction,您必须首先通过调用以下方法来确保您的表格是可编辑的:

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    //Obviously, if this returns no, the edit option won't even populate
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    //Nothing gets called here if you invoke `tableView:editActionsForRowAtIndexPath:` according to Apple docs so just leave this method blank
}

至少,这些是在继续之前需要声明的两种方法。

要实际自定义行动作按钮,请按照以下一般准则进行操作:

第1步实施tableView:editActionsForRowAtIndexPath:方法

-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
}

如您所见,它是NSArray类型的实例方法,因此您必须返回一个数组。

第2步添加操作对象以传入数组。一个例子:

{

UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
    // Delete something here
}];

UITableViewRowAction *more = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@" More " handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
    //Do whatever here : just as an example :
    [self presentUIAlertControllerActionSheet];
}];

}    

您可以更改这些行操作的一些属性,但请参阅文档以获取完整的自定义选项:

要自定义行动作背景颜色,只需像按钮中的大多数其他动作一样预先形成它:

delete.backgroundColor = [UIColor redColor];
more.backgroundColor = [UIColor colorWithRed:0.188 green:0.514 blue:0.984 alpha:1]; //arbitrary color

第3步 如前所述,您必须在实例方法中返回一个数组,因此您的完整代码应类似于以下内容:

-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
    {
        // Delete something here
    }];
    delete.backgroundColor = [UIColor redColor];

    UITableViewRowAction *more = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@" More " handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
    {
        //Just as an example :
        [self presentUIAlertControllerActionSheet];
    }];
    more.backgroundColor = [UIColor colorWithRed:0.188 green:0.514 blue:0.984 alpha:1];

    return @[delete, more]; //array with all the buttons you want. 1,2,3, etc...
}    

供进一步参考:LINK TO DOCUMENTATION


为SWIFT SYNTAX编辑

override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]?  {

var delete = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Delete" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
    //Do something
})
delete.backgroundColor = UIColor.redColor()

var more = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "More" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
    //Do something
})
more.backgroundColor = UIColor.blueColor()

    return [delete, more]
}

答案 1 :(得分:10)

@soulshined的所有荣誉都接受了答案。

这是它的Swift 3版本:

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
    let delete = UITableViewRowAction(style: .default, title: "Delete") { (action:UITableViewRowAction, indexPath:IndexPath) in
        print("delete at:\(indexPath)")
    }
    delete.backgroundColor = .red

    let more = UITableViewRowAction(style: .default, title: "More") { (action:UITableViewRowAction, indexPath:IndexPath) in
        print("more at:\(indexPath)")
    }
    more.backgroundColor = .orange

    return [delete, more]
}