[英]Full swipe UITableViewCell to delete UITableView iOS 8
I'd like to mimic the swipe to delete function of a UITableViewCell just like the mail app in iOS 8. I'm not referring to swipe to reveal a delete button. 我想模仿滑动删除UITableViewCell的功能,就像iOS 8中的邮件应用程序一样。我不是指滑动以显示删除按钮。 I'm referring to when you swipe, it discoloses 3 actions, but if you keep swiping to the left, the email is deleted. 我指的是当你刷卡时,它会破坏3个动作,但是如果你继续向左滑动,那么电子邮件就会被删除。
In iOS 8, UITableView has a new method where you can provide the data to display any number of buttons: 在iOS 8中,UITableView有一个新方法,您可以在其中提供数据以显示任意数量的按钮:
#ifdef __IPHONE_8_0
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewRowAction *viewStackRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Stack" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
SM_LOG_DEBUG(@"View Stack Action");
}];
viewStackRowAction.backgroundColor = [UIColor radiusBlueColor];
UITableViewRowAction *viewUserRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"User" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
SM_LOG_DEBUG(@"View User Action");
}];
viewUserRowAction.backgroundColor = [UIColor radiusLightBlueColor];
UITableViewRowAction *deleteRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
SM_LOG_DEBUG(@"Delete");
}];
deleteRowAction.backgroundColor = [UIColor redColor];
return @[deleteRowAction, viewUserRowAction, viewStackRowAction];
}
#endif
I don't see any API to detect if you keep swiping though. 我没有看到任何API来检测你是否继续刷卡。 I've grepped for 8_0 in UITableView.h and the above method seems to be the only new one. 我在UITableView.h中使用了8_0,上面的方法似乎是唯一的新方法。
I suppose one could monitor the scroll view offset, or add/hijack a UIPanGestureRecognizer. 我想可以监视滚动视图偏移,或添加/劫持UIPanGestureRecognizer。 I just wanted to make sure to use the default way, if there is one (and get the animation for "free") 我只是想确保使用默认方式,如果有的话(并获得“免费”动画)
With Swift 4.2 and iOS 12, according to your needs, you can choose one of the 3 following ways in order to create a trailing swipe action that will delete the selected UITableViewCell
. 使用Swift 4.2和iOS 12,您可以根据需要选择以下3种方法之一,以创建将删除所选UITableViewCell
的拖尾滑动操作。
UITableViewDataSource
's tableView(_:commit:forRowAt:)
使用UITableViewDataSource
的tableView(_:commit:forRowAt:)
When you use tableView(_:commit:forRowAt:)
with an editingStyle
of value UITableViewCell.EditingStyle.delete
, full swipe to delete is automatically supported by the system. 当您使用tableView(_:commit:forRowAt:)
和值为UITableViewCell.EditingStyle.delete
的editingStyle
,系统会自动支持完全滑动删除。
import UIKit
class TableViewController: UITableViewController {
var numbers = [Int](0..<10)
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numbers.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "\(numbers[indexPath.row])"
return cell
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCell.EditingStyle.delete) {
self.numbers.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
}
UITableViewDelegate
's tableView(_:editActionsForRowAt:)
and UITableViewRowAction
使用UITableViewDelegate
的tableView(_:editActionsForRowAt:)
和UITableViewRowAction
In order to support full swipe to delete with UITableViewRowAction
, you have to initialize it with a style
that has a value of UITableViewRowAction.Style.destructive
. 为了支持使用UITableViewRowAction
完全滑动删除,您必须使用值为UITableViewRowAction.Style.destructive
的style
对其进行初始化。
import UIKit
class TableViewController: UITableViewController {
var numbers = [Int](0..<10)
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numbers.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "\(numbers[indexPath.row])"
return cell
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
// Intentionally blank in order to be able to use UITableViewRowActions
}
override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let deleteHandler: (UITableViewRowAction, IndexPath) -> Void = { _, indexPath in
self.numbers.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
let deleteAction = UITableViewRowAction(style: UITableViewRowAction.Style.destructive, title: "Delete", handler: deleteHandler)
// Add more actions here if required
return [deleteAction]
}
}
UITableViewDelegate
's tableView(_:trailingSwipeActionsConfigurationForRowAt:)
and UISwipeActionsConfiguration
(requires iOS 11) 使用UITableViewDelegate
的tableView(_:trailingSwipeActionsConfigurationForRowAt:)
和UISwipeActionsConfiguration
(需要iOS 11) UISwipeActionsConfiguration
has a property called performsFirstActionWithFullSwipe
. UISwipeActionsConfiguration
有一个叫做财产performsFirstActionWithFullSwipe
。 performsFirstActionWithFullSwipe
has the following declaration: performsFirstActionWithFullSwipe
具有以下声明:
var performsFirstActionWithFullSwipe: Bool { get set }
A Boolean value indicating whether a full swipe automatically performs the first action. 一个布尔值,指示完全滑动是否自动执行第一个操作。 [...] When this property is set to
true
, a full swipe in the row performs the first action listed in theactions
property. [...]当此属性设置为true
,行中的完全滑动将执行actions
属性中列出的第一个操作。 The default value of this property istrue
. 此属性的默认值为true
。
The following UITableViewController
implementation show how to use UISwipeActionsConfiguration
in order to manage full swipe to delete actions. 以下UITableViewController
实现显示如何使用UISwipeActionsConfiguration
管理完全滑动以删除操作。
import UIKit
class TableViewController: UITableViewController {
var numbers = [Int](0..<10)
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numbers.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "\(numbers[indexPath.row])"
return cell
}
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let handler: UIContextualAction.Handler = { (action: UIContextualAction, view: UIView, completionHandler: ((Bool) -> Void)) in
self.numbers.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
completionHandler(true)
}
let deleteAction = UIContextualAction(style: UIContextualAction.Style.destructive, title: "Delete", handler: handler)
// Add more actions here if required
let configuration = UISwipeActionsConfiguration(actions: [deleteAction])
configuration.performsFirstActionWithFullSwipe = true
return configuration
}
}
add ui gustere recognizer to each cell, check the amount of "swipness", if its above specific threshold, do the deletion. 将ui gustere识别器添加到每个单元格中,检查“swipness”的数量,如果超过特定阈值,则执行删除操作。
somthing like: 像这样的东西:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]];
}
UISwipeGestureRecognizer* swipe_gesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeft:)];
[swipe_gesture setDirection:UISwipeGestureRecognizerDirectionLeft];
[cell addGestureRecognizer:swipe_gesture];
return cell;
}
- (void)swipeLeft:(UIGestureRecognizer *)gestureRecognizer {
int threshold = 100;
if (sender.state == UIGestureRecognizerStateBegan)
{
startLocation = [sender locationInView:self.view];
}
else if (sender.state == UIGestureRecognizerStateEnded)
{
CGPoint stopLocation = [sender locationInView:self.view];
CGFloat dx = stopLocation.x - startLocation.x;
CGFloat dy = stopLocation.y - startLocation.y;
CGFloat distance = sqrt(dx*dx + dy*dy );
if (distance > threshold )
{
NSLog(@"DELETE_ROW");
}
}
}
Your table view's data source has to implement 您的表视图的数据源必须实现
-tableView:commitEditingStyle:forRowAtIndexPath:
otherwise the built-in iOS 8 swiping functionality will not work. 否则内置的iOS 8滑动功能将无法正常工作。
This seems counterintuitive since a UITableViewRowAction
accepts a block. 这似乎违反直觉,因为UITableViewRowAction
接受一个块。 But it's the only way I've been able to get it to work. 但这是我能够让它发挥作用的唯一方法。
You can use MGSwipeTableCell . 您可以使用MGSwipeTableCell 。 They have implement this feature to fire callback swipeTableCell:tappedButtonAtIndex:direction:fromExpansion: with tappedButtonAtIndex equal to 0 (so it gets executed what you implemented on first added button). 他们已经实现了这个功能来触发回调swipeTableCell:tappedButtonAtIndex:direction:fromExpansion:tappedButtonAtIndex等于0(因此它会执行你在第一次添加的按钮上实现的内容)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.