滑动删除和“更多”;按钮(类似于iOS 7的邮件应用程序)

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

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

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

enter image description here

130926 次浏览

你需要子类UITableViewCell和子类方法willTransitionToState:(UITableViewCellStateMask)state,当用户滑动单元格时调用它。state标志会让你知道删除按钮是否显示,并在那里显示/隐藏你的更多按钮。

不幸的是,这个方法既没有给你Delete按钮的宽度,也没有给你动画时间。所以你需要一个观察者将More按钮的帧和动画时间硬编码到代码中(我个人认为苹果需要在这方面做些什么)。

我希望你不能等到苹果公司给你你想要的东西,对吗?这是我的选择。

创建自定义单元格。有两个uiview吗

1. upper
2. lower
在下视图中,添加任何你需要的按钮。公正对待其行为 像任何其他ibaction。你可以决定动画的时间,风格和任何东西

现在添加一个uiswipegesture到上视图,并显示你的下视图在滑动手势。我以前这样做过,就我而言,这是最简单的选择。

希望能有所帮助。

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

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

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

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

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

它们不言自明。

这里有一种有点脆弱的方法,它不涉及私有api或构造自己的系统。你在对冲赌注,苹果不会打破这一点,希望他们会发布一个API,你可以用它来替换这几行代码。

  1. 在init中执行此操作。这是UIScrollView的层。你不能KVO“子视图”。
  2. 这是在观察回调中完成的。
  3. 将该视图的大小扩大一倍,并在其唯一子视图的左侧添加一个UIButton。这也是在观察回调中完成的。删除确认视图的唯一子视图是删除按钮。
  4. (可选)UIButton事件应该查找self。superview,直到它找到一个UITableView,然后调用你创建的数据源或委托方法,比如tableView:commitCustomEditingStyle:forRowAtIndexPath:。你可以使用[tableView indexPathForCell:self]找到单元格的indexPath。

这还要求您实现标准表视图编辑委托回调。

static char kObserveContext = 0;


@implementation KZTableViewCell {
UIScrollView *_contentScrollView;
UIView *_confirmationView;
UIButton *_editButton;
UIButton *_deleteButton;
}


- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
_contentScrollView = (id)self.contentView.superview;


[_contentScrollView.layer addObserver:self
forKeyPath:@"sublayers"
options:0
context:&kObserveContext];


_editButton = [UIButton new];
_editButton.backgroundColor = [UIColor lightGrayColor];
[_editButton setTitle:@"Edit" forState:UIControlStateNormal];
[_editButton addTarget:self
action:@selector(_editTap)
forControlEvents:UIControlEventTouchUpInside];


}
return self;
}


-(void)dealloc {
[_contentScrollView.layer removeObserver:self forKeyPath:@"sublayers" context:&kObserveContext];
}


-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if(context != &kObserveContext) {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
return;
}
if(object == _contentScrollView.layer) {
for(UIView * view in _contentScrollView.subviews) {
if([NSStringFromClass(view.class) hasSuffix:@"ConfirmationView"]) {
_confirmationView = view;
_deleteButton = [view.subviews objectAtIndex:0];
CGRect frame = _confirmationView.frame;
CGRect frame2 = frame;
frame.origin.x -= frame.size.width;
frame.size.width *= 2;
_confirmationView.frame = frame;


frame2.origin = CGPointZero;
_editButton.frame = frame2;
frame2.origin.x += frame2.size.width;
_deleteButton.frame = frame2;
[_confirmationView addSubview:_editButton];
break;
}
}
return;
}
}


-(void)_editTap {
UITableView *tv = (id)self.superview;
while(tv && ![tv isKindOfClass:[UITableView class]]) {
tv = (id)tv.superview;
}
id<UITableViewDelegate> delegate = tv.delegate;
if([delegate respondsToSelector:@selector(tableView:editTappedForRowWithIndexPath:)]) {
NSIndexPath *ip = [tv indexPathForCell:self];
// define this in your own protocol
[delegate tableView:tv editTappedForRowWithIndexPath:ip];
}
}
@end

如何实施

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

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

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

< br >

已知的问题

文档说tableView:commitEditingStyle:forRowAtIndexPath是:

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

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

< br >

来源

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

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

< br >

更新:

这个工作的示例代码(在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];
}

我创建了一个新的库来实现可滑动的按钮,它支持各种过渡和可扩展的按钮,如iOS 8邮件应用程序。

https://github.com/MortimerGoro/MGSwipeTableCell < a href = " https://github.com/MortimerGoro/MGSwipeTableCell " > < / >

这个库兼容所有创建UITableViewCell的不同方法,它在iOS 5、iOS 6、iOS 7和iOS 8上进行了测试。

以下是一些过渡的例子:

边境的转变:

边界过渡

夹过渡

剪辑过渡

3 d的转变:

enter image description here

约翰尼的答案是正确的。我只是在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...
}
这里有一个简单的解决办法。它能够在UITableViewCell中显示和隐藏自定义UIView。 显示逻辑包含在从UITableViewCell, BaseTableViewCell扩展的类中

BaseTableViewCell.h

#import <UIKit/UIKit.h>


@interface BaseTableViewCell : UITableViewCell


@property(nonatomic,strong)UIView* customView;


-(void)showCustomView;


-(void)hideCustomView;


@end

BaseTableViewCell。米

#import "BaseTableViewCell.h"


@interface BaseTableViewCell()
{
BOOL _isCustomViewVisible;
}


@end


@implementation BaseTableViewCell


- (void)awakeFromNib {
// Initialization code
}


-(void)prepareForReuse
{
self.customView = nil;
_isCustomViewVisible = NO;
}


- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];


// Configure the view for the selected state
}


-(void)showCustomView
{
if(nil != self.customView)
{
if(!_isCustomViewVisible)
{
_isCustomViewVisible = YES;


if(!self.customView.superview)
{
CGRect frame = self.customView.frame;
frame.origin.x = self.contentView.frame.size.width;
self.customView.frame = frame;
[self.customView willMoveToSuperview:self.contentView];
[self.contentView addSubview:self.customView];
[self.customView didMoveToSuperview];
}


__weak BaseTableViewCell* blockSelf = self;
[UIView animateWithDuration:.5 animations:^(){


for(UIView* view in blockSelf.contentView.subviews)
{
CGRect frame = view.frame;
frame.origin.x = frame.origin.x - blockSelf.customView.frame.size.width;
view.frame = frame;
}
}];
}
}
}


-(void)hideCustomView
{
if(nil != self.customView)
{
if(_isCustomViewVisible)
{
__weak BaseTableViewCell* blockSelf = self;
_isCustomViewVisible = NO;
[UIView animateWithDuration:.5 animations:^(){
for(UIView* view in blockSelf.contentView.subviews)
{
CGRect frame = view.frame;
frame.origin.x = frame.origin.x + blockSelf.customView.frame.size.width;
view.frame = frame;
}
}];
}
}
}


@end

要获得此功能,只需从BaseTableViewCell扩展您的表视图单元格。

< p >下一步, 在UIViewController中,它实现了UITableViewDelegate,创建了两个手势识别器来处理左右滑动
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.


[self.tableView registerNib:[UINib nibWithNibName:CUSTOM_CELL_NIB_NAME bundle:nil] forCellReuseIdentifier:CUSTOM_CELL_ID];


UISwipeGestureRecognizer* leftSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleLeftSwipe:)];
leftSwipeRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
[self.tableView addGestureRecognizer:leftSwipeRecognizer];


UISwipeGestureRecognizer* rightSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleRightSwipe:)];
rightSwipeRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
[self.tableView addGestureRecognizer:rightSwipeRecognizer];
}

然后添加两个滑动处理程序

- (void)handleLeftSwipe:(UISwipeGestureRecognizer*)recognizer
{
CGPoint point = [recognizer locationInView:self.tableView];
NSIndexPath* index = [self.tableView indexPathForRowAtPoint:point];


UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:index];


if([cell respondsToSelector:@selector(showCustomView)])
{
[cell performSelector:@selector(showCustomView)];
}
}


- (void)handleRightSwipe:(UISwipeGestureRecognizer*)recognizer
{
CGPoint point = [recognizer locationInView:self.tableView];
NSIndexPath* index = [self.tableView indexPathForRowAtPoint:point];


UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:index];


if([cell respondsToSelector:@selector(hideCustomView)])
{
[cell performSelector:@selector(hideCustomView)];
}
}

现在,在UITableViewDelegate的cellForRowAtIndexPath中,你可以创建自定义UIView并将它附加到dequeuedcell中。

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCellTableViewCell* cell = (CustomCellTableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"CustomCellTableViewCell" forIndexPath:indexPath];


NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"CellCustomView"
owner:nil
options:nil];


CellCustomView* customView = (CellCustomView*)[ nibViews objectAtIndex: 0];


cell.customView = customView;


return cell;
}

当然,这种加载自定义UIView的方式只适用于这个例子。按照您的意愿管理它。

用于快速编程

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
}

以下内容可能会帮到你:

-(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...
}

我想在我的应用程序中添加相同的功能,在经历了这么多不同的教程(raywenderlich是最好的DIY解决方案)后,我发现苹果有自己的__abc0类,这非常方便。

你必须把Tableview的boilerpoint方法改成这样:

override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]?  {
// 1
var shareAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Share" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
// 2
let shareMenu = UIAlertController(title: nil, message: "Share using", preferredStyle: .ActionSheet)


let twitterAction = UIAlertAction(title: "Twitter", style: UIAlertActionStyle.Default, handler: nil)
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil)


shareMenu.addAction(twitterAction)
shareMenu.addAction(cancelAction)




self.presentViewController(shareMenu, animated: true, completion: nil)
})
// 3
var rateAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Rate" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
// 4
let rateMenu = UIAlertController(title: nil, message: "Rate this App", preferredStyle: .ActionSheet)


let appRateAction = UIAlertAction(title: "Rate", style: UIAlertActionStyle.Default, handler: nil)
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil)


rateMenu.addAction(appRateAction)
rateMenu.addAction(cancelAction)




self.presentViewController(rateMenu, animated: true, completion: nil)
})
// 5
return [shareAction,rateAction]
}

你可以在这个网站上找到更多关于这个的信息。Apple的自己的文档对于改变背景颜色非常有用:

操作按钮的背景色。

OBJECTIVE-C @property(nonatomic, copy) UIColor 使用此属性指定按钮的背景色。如果没有指定值 属性中的值为UIKit分配一个默认颜色 样式属性。< / p >

可用性iOS 8.0及以上版本支持。

如果你想改变按钮的字体,这就有点棘手了。我在SO上见过另一篇文章。为了提供代码和链接,这里是他们在那里使用的代码。你必须改变按钮的外观。你必须对tableviewcell做一个特定的引用,否则你会在整个应用程序中改变按钮的外观(我不想那样,但你可能会,我不知道:))

Objective - 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])

恕我直言,这是最简单、最流畅的版本。希望能有所帮助。

更新:这是Swift 3.0版本:

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
var shareAction:UITableViewRowAction = UITableViewRowAction(style: .default, title: "Share", handler: {(action, cellIndexpath) -> Void in
let shareMenu = UIAlertController(title: nil, message: "Share using", preferredStyle: .actionSheet)


let twitterAction = UIAlertAction(title: "Twitter", style: .default, handler: nil)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)


shareMenu.addAction(twitterAction)
shareMenu.addAction(cancelAction)




self.present(shareMenu,animated: true, completion: nil)
})


var rateAction:UITableViewRowAction = UITableViewRowAction(style: .default, title: "Rate" , handler: {(action, cellIndexpath) -> Void in
// 4
let rateMenu = UIAlertController(title: nil, message: "Rate this App", preferredStyle: .actionSheet)


let appRateAction = UIAlertAction(title: "Rate", style: .default, handler: nil)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)


rateMenu.addAction(appRateAction)
rateMenu.addAction(cancelAction)




self.present(rateMenu, animated: true, completion: nil)
})
// 5
return [shareAction,rateAction]
}

为了改进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];
}

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]
}


}

Swift 3实际回答

这是你唯一需要的功能。对于自定义操作,您不需要CanEdit或CommitEditingStyle函数。

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let action1 = UITableViewRowAction(style: .default, title: "Action1", handler: {
(action, indexPath) in
print("Action1")
})
action1.backgroundColor = UIColor.lightGray
let action2 = UITableViewRowAction(style: .default, title: "Action2", handler: {
(action, indexPath) in
print("Action2")
})
return [action1, action2]
}

有一个神奇的库叫做SwipeCellKit,它应该得到更多的认可。在我看来,它比MGSwipeTableCell更酷。后者不完全复制邮件应用程序的单元格的行为,而SwipeCellKit可以。看一看

从iOS 11开始,它在UITableViewDelegate中公开可用。下面是一些示例代码:

斯威夫特

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

斯威夫特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
}

Swift 4 &iOs 11 +

@available(iOS 11.0, *)
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {


let delete = UIContextualAction(style: .destructive, title: "Delete") { _, _, handler in


handler(true)
// handle deletion here
}


let more = UIContextualAction(style: .normal, title: "More") { _, _, handler in


handler(true)
// handle more here
}


return UISwipeActionsConfiguration(actions: [delete, more])
}

我使用tableViewCell来显示多个数据,在一个单元格上从右向左滑动()后,它将显示两个按钮批准和拒绝,有两个方法,第一个是ApproveFunc,它接受一个参数,另一个是RejectFunc,它也接受一个参数。

enter image description here

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let Approve = UITableViewRowAction(style: .normal, title: "Approve") { action, index in


self.ApproveFunc(indexPath: indexPath)
}
Approve.backgroundColor = .green


let Reject = UITableViewRowAction(style: .normal, title: "Reject") { action, index in


self.rejectFunc(indexPath: indexPath)
}
Reject.backgroundColor = .red






return [Reject, Approve]
}


func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}


func ApproveFunc(indexPath: IndexPath) {
print(indexPath.row)
}
func rejectFunc(indexPath: IndexPath) {
print(indexPath.row)
}