完全滑动UITableView单元格以删除UITableView iOS 8

完全滑动UITableView单元格以删除UITableView iOS 8,ios,uitableview,ios8,uipangesturerecognizer,Ios,Uitableview,Ios8,Uipangesturerecognizer,我想模仿UITableViewCell的滑动删除功能,就像iOS 8中的邮件应用一样。我指的不是滑动以显示删除按钮。我指的是当你刷卡时,它会丢失3个动作,但如果你继续向左刷卡,电子邮件会被删除 在iOS 8中,UITableView有一种新方法,您可以提供数据以显示任意数量的按钮: #ifdef __IPHONE_8_0 - (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPat

我想模仿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,上面的方法似乎是唯一的新方法


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

将ui gustere识别器添加到每个单元格,检查“swipness”的数量,如果其超过特定阈值,则执行删除操作

有点像:

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

    }
}

表视图的数据源必须实现

-tableView:commitEditingStyle:forRowAtIndexPath:
否则,内置的iOS 8刷卡功能将无法工作


这似乎违反直觉,因为
UITableViewRowAction
接受块。但这是我能让它工作的唯一方法。

你可以使用。他们已经实现了这个功能来触发回叫swipeTableCell:TappedButtonIndex:direction:fromExpansion:TappedButtonIndex等于0(因此它会执行您在第一个添加的按钮上实现的操作)。

根据您的需要,使用Swift 4.2和iOS 12,您可以选择以下三种方式之一,以创建将删除选定的
UITableViewCell
的后续滑动操作


#1.使用
UITableViewDataSource
当您使用
tableView(uu: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)
        }
    }

}

#3.使用
UITableViewDelegate
和(需要iOS 11)
UISwipeActionsConfiguration
有一个名为的属性
performsFirstActionWithFullSwipe
具有以下声明:

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

以下
UITableViewController
实现展示了如何使用
uisweepactionsconfiguration
来管理完全滑动以删除操作

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
    }

}
导入UIKit
类TableViewController:UITableViewController{
变量编号=[Int](0..Int{
返回数字。计数
}
重写func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
let cell=tableView.dequeueReusableCell(带有标识符:“cell”,用于:indexath)
cell.textlab?.text=“\(数字[indexPath.row])”
返回单元
}
重写func tableView(tableView:UITableView,TrailingSwipeActionsConfiguration for Rowat indexPath:indexPath)->UISwipeActionsConfiguration{
让handler:UIContextualAction.handler={(操作:UIContextualAction,视图:UIView,completionHandler:((Bool)->Void))位于
self.numbers.remove(位于:indexPath.row)
tableView.deleteRows(位于:[indexPath],带:.fade)
completionHandler(true)
}
让deleteAction=UIContextualAction(样式:UIContextualAction.style.destructive,标题:“删除”,处理程序:处理程序)
//如果需要,在此处添加更多操作
let configuration=UISwipeActionsConfiguration(操作:[deleteAction])
configuration.performsFirstActionWithFullSwipe=true
返回配置
}
}

这不允许完全滑动删除表格单元格。它允许显示“删除”按钮,用户仍然需要按按钮删除。您好。如果您更具体,解释得更详细,效果会更好。在swipeLeft方法中,您使用的是sender和startLocation。它们来自何处?您在何处添加这些方法?谢谢,我很高兴看到他们添加了这个。
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
    }

}