在 UITableView 滑动中添加额外的按钮
add additional buttons in UITableView swipe
目前我正在使用 NSFetchedResultsController 来处理表格视图。
我想知道有没有办法在滑动操作中添加额外的按钮,比如删除按钮?
我正在考虑将其子类化。但是在帮助文档中找不到与我的问题相关的内容。
提前致谢。
您的标题具有误导性。 NSFetchedResultsController 与您的最终目标无关。子类化只会产生比必要更多的工作,你想要研究的是 UITableViewRowAction
。这与新的 UIAlertController
处理起来非常容易且相似,所以如果您已经尝试过 UIAlertController
,您应该对 table 感到非常舒服
UITableViewRowAction
的简要介绍(直接来自 the docs):
Asks the delegate for the actions to display in response to a swipe in the specified row. (required)
Use this method when you want to provide custom actions for one of your table rows. When the user swipes horizontally in a row, the table view moves the row content aside to reveal your actions. Tapping one of the action buttons executes the handler block stored with the action object.
If you do not implement this method, the table view displays the standard accessory buttons when the user swipes the row.
开始前的几点说明:
- Apple 在 iOS8 中实现了这一点:因此请仔细考虑您的部署目标。如果您严格地为 i0S8 编码,这是替代第 3 方库或创建自定义 UITableView 编辑样式的快速简便的方法。如果您的目标是保持与 iOS7 的兼容性,您的选项将受限于此格式。 旁注这不会在您的代码中导致致命错误,iOS7应用程序不会崩溃,但是,自定义操作根本不会显示。
- 除了标题之外没有太多定制
- 这样做的优点是,一切都用块处理
无论如何,要实现自定义 UITableViewRowAction
,您必须首先通过调用以下方法确保您的 table 是 editable:
- (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 类型的实例方法,因此您必须 return 一个数组。
步骤 2 添加操作 objects 以传入数组。一个例子:
{
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 步
如前所述,您必须在实例方法中 return 一个数组,因此您的完整代码应类似于以下内容:
-(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 语法进行编辑
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]
}
感谢@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]
}
目前我正在使用 NSFetchedResultsController 来处理表格视图。 我想知道有没有办法在滑动操作中添加额外的按钮,比如删除按钮?
我正在考虑将其子类化。但是在帮助文档中找不到与我的问题相关的内容。
提前致谢。
您的标题具有误导性。 NSFetchedResultsController 与您的最终目标无关。子类化只会产生比必要更多的工作,你想要研究的是 UITableViewRowAction
。这与新的 UIAlertController
处理起来非常容易且相似,所以如果您已经尝试过 UIAlertController
UITableViewRowAction
的简要介绍(直接来自 the docs):
Asks the delegate for the actions to display in response to a swipe in the specified row. (required) Use this method when you want to provide custom actions for one of your table rows. When the user swipes horizontally in a row, the table view moves the row content aside to reveal your actions. Tapping one of the action buttons executes the handler block stored with the action object. If you do not implement this method, the table view displays the standard accessory buttons when the user swipes the row.
开始前的几点说明:
- Apple 在 iOS8 中实现了这一点:因此请仔细考虑您的部署目标。如果您严格地为 i0S8 编码,这是替代第 3 方库或创建自定义 UITableView 编辑样式的快速简便的方法。如果您的目标是保持与 iOS7 的兼容性,您的选项将受限于此格式。 旁注这不会在您的代码中导致致命错误,iOS7应用程序不会崩溃,但是,自定义操作根本不会显示。
- 除了标题之外没有太多定制
- 这样做的优点是,一切都用块处理
无论如何,要实现自定义 UITableViewRowAction
,您必须首先通过调用以下方法确保您的 table 是 editable:
- (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 类型的实例方法,因此您必须 return 一个数组。
步骤 2 添加操作 objects 以传入数组。一个例子:
{
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 步 如前所述,您必须在实例方法中 return 一个数组,因此您的完整代码应类似于以下内容:
-(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 语法进行编辑
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]
}
感谢@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]
}