我一直在这里和Cocoa Touch论坛上寻找这些信息,但似乎找不到答案,希望有比我更聪明的人能给我一个解决方案。
当用户滑动表视图单元格时,我想显示不止一个编辑按钮(默认是删除按钮)。在iOS 7的邮件应用程序中,您可以向左滑动以删除,但会出现一个“更多”按钮。
看起来iOS 8开放了这个API。这种功能的提示在Beta 2中存在。
要使某些东西工作,需要在您的UITableView的委托上实现以下两种方法以获得所需的效果(请参见gist中的示例)。
- tableView:editActionsForRowAtIndexPath:
- tableView:commitEditingStyle:forRowAtIndexPath:
文档中说tableView:commitEditingStyle:forRowAtIndexPath方法不会被UITableViewRowAction调用,而是会调用action的处理程序。然而,没有这个方法就无法进行滑动操作。即使方法存根为空,现在仍需要它。这显然是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];
}
tableView.editing = false
(NO
in objc),这样单元格就会“关闭”。 - Ben Lachman我创建了一个新的库,用于实现可滑动按钮,支持多种过渡效果和可扩展的按钮,就像iOS 8邮件应用程序。
https://github.com/MortimerGoro/MGSwipeTableCell
该库与所有不同的UITableViewCell创建方式兼容,并已在iOS 5、iOS 6、iOS 7和iOS 8上进行了测试。
以下是一些转换示例:
边框转换:
剪辑转换:
3D转换:
Johnny的回答是正确的,应该点赞。我在下面使用objective-c添加了一些内容,以使初学者更加清晰(还有那些拒绝学习Swift语法的人们):)
确保你声明了uitableviewdelegate并具备以下方法:
-(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...
}
这是一个(相当荒谬的)私有 API。
以下两种方法是私有的,并发送给 UITableView 的代理:
-(NSString *)tableView:(UITableView *)tableView titleForSwipeAccessoryButtonForRowAtIndexPath:(NSIndexPath *)indexPath;
-(void)tableView:(UITableView *)tableView swipeAccessoryButtonPushedForRowAtIndexPath:(NSIndexPath *)indexPath;
它们相当容易理解。
为了改善Johnny的回答,现在可以按照以下方式使用公共API进行操作:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let moreRowAction = UITableViewRowAction(style: UITableViewRowActionStyle.default, title: "More", handler:{action, indexpath in
print("MORE•ACTION");
});
moreRowAction.backgroundColor = UIColor(red: 0.298, green: 0.851, blue: 0.3922, alpha: 1.0);
let deleteRowAction = UITableViewRowAction(style: UITableViewRowActionStyle.default, title: "Delete", handler:{action, indexpath in
print("DELETE•ACTION");
});
return [deleteRowAction, moreRowAction];
}
我希望你迫不及待地想要苹果公司提供你所需的一切,对吗?那么这是我的建议。
创建一个自定义单元格,在其中放置两个UIViews。
1. upper
2. lower
在低视图中,添加任何你需要的按钮。像处理其他IBAction一样处理它的操作。你可以决定动画时间、风格以及任何东西。
现在,在上视图中添加一个uiswipegesture,在滑动手势中显示你的下视图。我以前做过这个,就我而言,这是最简单的选项。
希望能有所帮助。
UITableViewCellScrollView
(UITableViewCell
的私有子视图)下方放置第二个UISScrollView,还有一些则修改了UITableViewCellScrollView
的行为。UITableViewCell
子视图层次结构中进行更改,则这些解决方案很容易在未来的iOS版本中出现故障。不使用任何库的Swift 3版本代码:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView.tableFooterView = UIView(frame: CGRect.zero) //Hiding blank cells.
tableView.separatorInset = UIEdgeInsets.zero
tableView.dataSource = self
tableView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath)
return cell
}
//Enable cell editing methods.
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let more = UITableViewRowAction(style: .normal, title: "More") { action, index in
//self.isEditing = false
print("more button tapped")
}
more.backgroundColor = UIColor.lightGray
let favorite = UITableViewRowAction(style: .normal, title: "Favorite") { action, index in
//self.isEditing = false
print("favorite button tapped")
}
favorite.backgroundColor = UIColor.orange
let share = UITableViewRowAction(style: .normal, title: "Share") { action, index in
//self.isEditing = false
print("share button tapped")
}
share.backgroundColor = UIColor.blue
return [share, favorite, more]
}
}
UITableViewCell
的子类,并重写willTransitionToState:(UITableViewCellStateMask)state
方法。每当用户滑动单元格时,该方法都会被调用。通过检查state
标志,您可以知道是否正在显示删除按钮,并在那里显示/隐藏您的“更多”按钮。从 iOS 11 开始,这个功能已经在 UITableViewDelegate
中公开。以下是一些示例代码:
Swift
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .normal, title: nil) { (_, _, _) in
print("Swipe action tapped")
}
action.image = UIImage(systemName: "plus.slash.minus")
action.backgroundColor = .green
return UISwipeActionsConfiguration(actions: [action])
}
Objective C
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
UIContextualAction *delete = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive
title:@"DELETE"
handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
NSLog(@"index path of delete: %@", indexPath);
completionHandler(YES);
}];
UIContextualAction *rename = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal
title:@"RENAME"
handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
NSLog(@"index path of rename: %@", indexPath);
completionHandler(YES);
}];
UISwipeActionsConfiguration *swipeActionConfig = [UISwipeActionsConfiguration configurationWithActions:@[rename, delete]];
swipeActionConfig.performsFirstActionWithFullSwipe = NO;
return swipeActionConfig;
}
还可用:
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath;
文档:https://developer.apple.com/documentation/uikit/uitableviewdelegate/2902367-tableview?language=objc