当用户在表格视图中滑动单元格时,如何创建一个“更多”按钮(就像ios 7中的邮件应用程序)

我一直在这里和Cocoa Touch论坛上寻找这些信息,但我似乎找不到答案,我希望比我更聪明的人能给我一个解决方案。

我希望当用户滑动一个表格视图单元格时,显示多个编辑按钮(默认是删除按钮)。 在iOS 7的邮件应用程序中,你可以滑动删除,但会出现一个“更多”按钮。


当前回答

斯威夫特4

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let delete = UIContextualAction(style: .destructive, title: "Delete") { (action, sourceView, completionHandler) in
        print("index path of delete: \(indexPath)")
        completionHandler(true)
    }
    let rename = UIContextualAction(style: .normal, title: "Edit") { (action, sourceView, completionHandler) in
        print("index path of edit: \(indexPath)")
        completionHandler(true)
    }
    let swipeActionConfig = UISwipeActionsConfiguration(actions: [rename, delete])
    swipeActionConfig.performsFirstActionWithFullSwipe = false
    return swipeActionConfig
}

其他回答

这是一个(相当可笑的)私有API。

下面两个方法是私有的,并且被发送给UITableView的委托:

-(NSString *)tableView:(UITableView *)tableView titleForSwipeAccessoryButtonForRowAtIndexPath:(NSIndexPath *)indexPath;
-(void)tableView:(UITableView *)tableView swipeAccessoryButtonPushedForRowAtIndexPath:(NSIndexPath *)indexPath;

它们不言自明。

以下内容可能会帮到你:

-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewRowAction *button = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Button 1" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
    {
        NSLog(@"Action to perform with Button 1");
    }];
    button.backgroundColor = [UIColor greenColor]; //arbitrary color
    UITableViewRowAction *button2 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Button 2" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
                                    {
                                        NSLog(@"Action to perform with Button2!");
                                    }];
    button2.backgroundColor = [UIColor blueColor]; //arbitrary color

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

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    // you need to implement this method too or nothing will work:
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    return YES; //tableview must be editable or nothing will work...
}

斯威夫特4

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let delete = UIContextualAction(style: .destructive, title: "Delete") { (action, sourceView, completionHandler) in
        print("index path of delete: \(indexPath)")
        completionHandler(true)
    }
    let rename = UIContextualAction(style: .normal, title: "Edit") { (action, sourceView, completionHandler) in
        print("index path of edit: \(indexPath)")
        completionHandler(true)
    }
    let swipeActionConfig = UISwipeActionsConfiguration(actions: [rename, delete])
    swipeActionConfig.performsFirstActionWithFullSwipe = false
    return swipeActionConfig
}

使用标准SDK是不可能实现的。然而,有各种各样的第三方解决方案或多或少地模仿了Mail.app中的行为。其中一些(例如MCSwipeTableViewCell, DAContextMenuTableViewController, RMSwipeTableViewCell)使用手势识别器检测滑动,其中一些(例如SWTableViewCell)在标准UITableViewCellScrollView (UITableViewCell的私有子视图)下面放置第二个UISScrollView,其中一些修改UITableViewCellScrollView的行为。

我最喜欢最后一种方法,因为触摸操作感觉最自然。具体来说,MSCMoreOptionTableViewCell很好。你的选择可能会根据你的具体需求而有所不同(你是否也需要从左到右平移,是否需要iOS 6兼容性等等)。还要注意,大多数这些方法都有一个负担:如果苹果在UITableViewCell子视图层次结构中做了改变,它们很容易在未来的iOS版本中被打破。

如何实施

看起来iOS 8打开了这个API。在Beta 2中有这样的功能提示。

为了让某些东西工作,在你的UITableView的委托上实现以下两个方法以获得所需的效果(参见示例的要点)。

- tableView:editActionsForRowAtIndexPath:
- tableView:commitEditingStyle:forRowAtIndexPath:

已知的问题

文档说tableView:commitEditingStyle:forRowAtIndexPath是:

使用uitableviewwroaction的编辑操作不会被调用——操作的处理程序将被调用。

然而,没有它,滑动就不能工作。即使方法存根是空白的,它现在仍然需要它。这显然是beta 2中的一个bug。

来源

https://twitter.com/marksands/status/481642991745265664 https://gist.github.com/marksands/76558707f583dbb8f870

原答案:https://stackoverflow.com/a/24540538/870028

更新:

示例代码与此工作(在Swift中):http://dropbox.com/s/0fvxosft2mq2v5m/DeleteRowExampleSwift.zip

示例代码在MasterViewController.swift中包含了这个易于遵循的方法,通过这个方法你可以得到OP截图中显示的行为:

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

    var moreRowAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "More", handler:{action, indexpath in
        println("MORE•ACTION");
    });
    moreRowAction.backgroundColor = UIColor(red: 0.298, green: 0.851, blue: 0.3922, alpha: 1.0);

    var deleteRowAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Delete", handler:{action, indexpath in
        println("DELETE•ACTION");
    });

    return [deleteRowAction, moreRowAction];
}