完全滑动UITableViewCell以删除UITableView iOS 8

时间:2014-09-23 19:00:41

标签: ios uitableview ios8 uipangesturerecognizer

我想模仿滑动删除UITableViewCell的功能,就像iOS 8中的邮件应用程序一样。我不是指滑动以显示删除按钮。我指的是当你刷卡时,它会破坏3个动作,但是如果你继续向左滑动,那么电子邮件就会被删除。

在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

我没有看到任何API来检测你是否继续刷卡。我在UITableView.h中使用了8_0,上面的方法似乎是唯一的新方法。

我想可以监视滚动视图偏移,或添加/劫持UIPanGestureRecognizer。我只是想确保使用默认方式,如果有的话(并获得“免费”动画)

4 个答案:

答案 0 :(得分:3)

使用Swift 4.2和iOS 12,您可以根据需要选择以下3种方式之一,以创建将删除所选UITableViewCell的尾随滑动操作。

#1。使用UITableViewDataSource' s tableView(_:commit:forRowAt:)

当您使用tableView(_:commit:forRowAt:)值为editingStyle的{​​{1}}时,系统会自动支持完全滑动删除。

UITableViewCell.EditingStyle.delete

#2。使用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) } } } &#39; s tableView(_:editActionsForRowAt:)UITableViewRowAction

为了支持使用UITableViewDelegate完全滑动以进行删除,您必须使用值UITableViewRowAction的{​​{1}}对其进行初始化。

style

#3。使用UITableViewRowAction.Style.destructive&#39; tableView(_:trailingSwipeActionsConfigurationForRowAt:)UISwipeActionsConfiguration(需要iOS 11)

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] } } 有一个名为performsFirstActionWithFullSwipe的属性。 UITableViewDelegate有以下声明:

UISwipeActionsConfiguration
  

一个布尔值,指示完全滑动是否自动执行第一个操作。 [...]当此属性设置为performsFirstActionWithFullSwipe时,行中的完整滑动会执行var performsFirstActionWithFullSwipe: Bool { get set } 属性中列出的第一个操作。此属性的默认值为true

以下actions实施说明如何使用true来管理完全滑动以删除操作。

UITableViewController

答案 1 :(得分:2)

将ui gustere识别器添加到每个单元格中,检查&#34; swipness&#34;的数量,如果超出特定阈值,则执行删除。

像:

    - (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");
        }

    }
}

答案 2 :(得分:0)

您的表格视图的数据源实施

-tableView:commitEditingStyle:forRowAtIndexPath:

否则内置的iOS 8滑动功能将无效。

这似乎违反直觉,因为UITableViewRowAction接受了一个块。但这是我能够让它发挥作用的唯一方式。

答案 3 :(得分:0)

您可以使用MGSwipeTableCell。他们已经实现了这个功能来触发回调swipeTableCell:tappedButtonAtIndex:direction:fromExpansion:tappedButtonAtIndex等于0(所以它会执行你在第一次添加的按钮上实现的内容)。