-(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...
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
deleteModelAt(indexPath.row)
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
}
else if editingStyle == UITableViewCellEditingStyle.Insert {
println("insert editing action")
}
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
var archiveAction = UITableViewRowAction(style: .Default, title: "Archive",handler: { (action: UITableViewRowAction!, indexPath: NSIndexPath!) in
// maybe show an action sheet with more options
self.tableView.setEditing(false, animated: false)
}
)
archiveAction.backgroundColor = UIColor.lightGrayColor()
var deleteAction = UITableViewRowAction(style: .Normal, title: "Delete",
handler: { (action: UITableViewRowAction!, indexPath: NSIndexPath!) in
self.deleteModelAt(indexPath.row)
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic);
}
);
deleteAction.backgroundColor = UIColor.redColor()
return [deleteAction, archiveAction]
}
func deleteModelAt(index: Int) {
//... delete logic for model
}
3
这可以帮助你OUT .
-(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...
}
如果你想改变按钮的字体,那么's a bit more tricky. I'已经在SO上看到了another post . 为了提供代码和链接,这里's the code they used there. You' d必须改变按钮的外观 . 你'd have to make a specific reference to tableviewcell, otherwise you' d改变按钮's appearance throughout your app (I didn' t想要那个,但你可能,我不知道:))
目标C:
+ (void)setupDeleteRowActionStyleForUserCell {
UIFont *font = [UIFont fontWithName:@"AvenirNext-Regular" size:19];
NSDictionary *attributes = @{NSFontAttributeName: font,
NSForegroundColorAttributeName: [UIColor whiteColor]};
NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString: @"DELETE"
attributes: attributes];
/*
* We include UIView in the containment hierarchy because there is another button in UserCell that is a direct descendant of UserCell that we don't want this to affect.
*/
[[UIButton appearanceWhenContainedIn:[UIView class], [UserCell class], nil] setAttributedTitle: attributedTitle
forState: UIControlStateNormal];
}
迅速:
//create your attributes however you want to
let attributes = [NSFontAttributeName: UIFont.systemFontOfSize(UIFont.systemFontSize())] as Dictionary!
//Add more view controller types in the []
UIButton.appearanceWhenContainedInInstancesOfClasses([ViewController.self])
有一个名为 SwipeCellKit 的惊人库,它应该获得更多的认可 . 在我看来,它比 MGSwipeTableCell 更酷 . 后者不是't completely replicate the behavior of the Mail app'的细胞而 SwipeCellKit . Have a look
1
Swift 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
}
20 回答
如何实施
看起来iOS 8打开了这个API . Beta 2中提供了此类功能的提示 .
要使某些工作正常,请在UITableView的委托上实现以下两种方法以获得所需的效果(请参阅gist以获取示例) .
已知问题
文档说tableView:commitEditingStyle:forRowAtIndexPath是:
但是,如果没有它,滑动就无法工作 . 即使方法存根是空白的,它现在仍然需要它 . 这显然是beta 2中的一个错误 .
来源
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屏幕截图中显示的行为:
我创建了一个新的库来实现可交换按钮,它支持各种转换和可扩展按钮,如iOS 8邮件应用程序 .
https://github.com/MortimerGoro/MGSwipeTableCell
该库兼容所有不同的创建UITableViewCell的方法,并在iOS 5,iOS 6,iOS 7和iOS 8上进行测试 .
这里有一些过渡的样本:
边境过渡:
剪辑转换
3D过渡:
约翰尼的回答是正确的回答 . 我只是在objective-c中添加以下内容,以使初学者(以及那些拒绝学习Swift语法的人)更清楚:)
确保声明uitableviewdelegate并具有以下方法:
这是(相当荒谬)一个私有API .
以下两个方法是私有的并发送到UITableView的委托:
他们非常自我解释 .
为了改进Johnny的答案,现在可以使用公共API完成此操作,如下所示:
我希望你不能等到苹果给你什么,你需要什么?所以这是我的选择 .
创建自定义单元格 . 有两个uiviews
在下方视图中,添加您需要的按钮 . 像任何其他IBActions一样处理其行为 . 你可以决定动画的时间,风格和任何东西 .
现在在上方视图中添加一个uiswipegesture,并在滑动手势上显示您的下方视图 . 我以前做过这个,就我而言,它是最简单的选择 .
希望有所帮助 .
使用标准SDK无法做到这一点 . 但是,有各种第三方解决方案或多或少地模仿Mail.app中的行为 . 其中一些(例如MCSwipeTableViewCell,DAContextMenuTableViewController,RMSwipeTableViewCell)使用手势识别器检测滑动,其中一些(例如SWTableViewCell)将第二个UISScrollView置于标准
UITableViewCellScrollView
(UITableViewCell
的私有子视图)之下,其中一些修改了UITableViewCellScrollView
的行为 .我最喜欢最后一种方法,因为触摸处理感觉最自然 . 具体来说,MSCMoreOptionTableViewCell很好 . 您的选择可能会根据您的具体需求而有所不同(无论您是否需要从左到右的平底锅,是否需要iOS 6兼容性等) . 另请注意,大多数这些方法都有负担:如果Apple在
UITableViewCell
子视图层次结构中进行更改,它们很容易在未来的iOS版本中中断 .Swift 3 version code without using any library:
您需要子类化
UITableViewCell
和子类方法willTransitionToState:(UITableViewCellStateMask)state
,只要用户滑动单元格就会调用它 . 如果显示“删除”按钮,state
标志将通知您,并在那里显示/隐藏“更多”按钮 .不幸的是,这种方法既不提供删除按钮的宽度也不提供动画时间 . 因此,您需要观察并将您的更多按钮的帧和动画时间硬编码到您的代码中(我个人认为Apple需要对此做些什么) .
用于快速编程
这可以帮助你OUT .
我想在我的应用程序中添加相同的功能,经过这么多不同的教程(raywenderlich是最好的DIY解决方案)之后,我发现Apple有自己的
UITableViewRowAction
类,这非常方便 .您必须将Tableview的boilerpoint方法更改为:
您可以在This Site上找到更多相关信息 . Apple的own documentation对于更改背景颜色非常有用:
如果你想改变按钮的字体,那么's a bit more tricky. I'已经在SO上看到了another post . 为了提供代码和链接,这里's the code they used there. You' d必须改变按钮的外观 . 你'd have to make a specific reference to tableviewcell, otherwise you' d改变按钮's appearance throughout your app (I didn' t想要那个,但你可能,我不知道:))
目标C:
迅速:
这是最简单,最流线型的版本恕我直言 . 希望能帮助到你 .
更新:这是Swift 3.0版本:
Actual Swift 3 Answer
这是您需要的唯一功能 . 您不需要CanEdit或CommitEditingStyle函数来执行自定义操作 .
从iOS 11开始,这在
UITableViewDelegate
中公开 . 这是一些示例代码:也提供:
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath;
文件:https://developer.apple.com/documentation/uikit/uitableviewdelegate/2902367-tableview?language=objc
Swift 4&iOs 11
这是一种有点脆弱的方式,不涉及私有API或构建自己的系统 . 你正在对冲苹果公司没有打破这一点的赌注,希望他们能够发布一个API,你可以用这几行代码代替 .
KVO self.contentView.superview.layer.sublayer. 在init中执行此操作 . 这是UIScrollView 's layer. You can' t KVO 'subviews' .
When subviews changes, find the delete confirmation view within scrollview.subviews. 这是在observe回调中完成的 .
Double the size of that view and add a UIButton to the left of its only subview. 这也是在observe回调中完成的 . 删除确认视图的唯一子视图是删除按钮 .
(可选)UIButton事件应查找self.superview,直到找到UITableView,然后调用您创建的数据源或委托方法,例如tableView:commitCustomEditingStyle:forRowAtIndexPath: . 您可以使用[tableView indexPathForCell:self]找到单元格的indexPath .
这还要求您实现标准表视图编辑委托回调 .
有一个名为
SwipeCellKit
的惊人库,它应该获得更多的认可 . 在我看来,它比MGSwipeTableCell
更酷 . 后者不是't completely replicate the behavior of the Mail app'的细胞而SwipeCellKit
. Have a lookSwift 4
我使用 tableViewCell 来显示多个数据,在一个单元格上向右滑动()后会显示两个按钮Approve和reject,有两个方法,第一个是ApproveFunc,它接受一个参数,另一个是RejectFunc,它也是有一个论点 .
这是一个简单的解决方案 . 它能够在UITableViewCell中显示和隐藏自定义UIView . 显示逻辑包含在从UITableViewCell,BaseTableViewCell扩展的类中 .
BaseTableViewCell.h
BaseTableViewCell.M
要获得此功能,只需从BaseTableViewCell扩展表视图单元 .
接下来,实现UITableViewDelegate的Inside UIViewController创建了两个手势识别器来处理左右滑动 .
比添加两个滑动处理程序
现在,在UITableViewDelegate的cellForRowAtIndexPath中,您可以创建自定义UIView并将其附加到出列单元格 .
当然,这种加载自定义UIView的方式仅适用于此示例 . 根据需要管理它 .