iOS - 如何查看表格视图单元格上的“滑动删除”操作?

Posted

技术标签:

【中文标题】iOS - 如何查看表格视图单元格上的“滑动删除”操作?【英文标题】:iOS - How To Give A Peek At The "Swipe To Delete" Action On A Table View Cell? 【发布时间】:2019-04-09 11:45:23 【问题描述】:

当某个 Table View Controller 第一次显示时,如何简单的显示一个表格行中存在红色的“滑动删除”功能?

以编程方式玩 peekaboo 的目的是向用户展示该功能的存在。

环境:ios 11+ 和 iPhone 应用。

这是一张图片,显示单元格中途滑动,带有一个基本的“滑动删除”红色操作按钮。

一位开发人员友好地提到了 SwipeCellKit,但 SwipeCellKit 有很多东西。我们要做的只是简单地模拟部分滑动,让用户知道“滑动删除”的存在。换句话说,我们希望在单元格下的删除操作中提供一个偷偷摸摸的峰值。

如果有帮助,这里是SwipeCellKit's showSwipe code 的链接这是link with an example of its use。

我查看了 SwipeCellKit 源代码。如果没有 SwipeCellKit,我不清楚如何做到这一点。此外,目前还不能选择使用 SwipeCellKit。

谷歌搜索没有帮助。我一直遇到how to add swipe actions,但不知道如何向用户简要地显示单元格下的滑动操作(即 UITableViewRowAction)项。

如何向用户简要展示这个内置的“滑动删除”操作?

【问题讨论】:

【参考方案1】:

我为UITableView 编写了这个简单的扩展。它搜索可见单元格,找到包含编辑操作的第一行,然后执行魔术。您可以调整提示的宽度和持续时间等参数。

效果很好,因为它不会硬编码任何值,因此例如提示的背景颜色将始终与实际操作按钮匹配。

import UIKit

extension UITableView 
    /**
     Shows a hint to the user indicating that cell can be swiped left.
     - Parameters:
        - width: Width of hint.
        - duration: Duration of animation (in seconds)
     */
    func presentTrailingSwipeHint(width: CGFloat = 20, duration: TimeInterval = 0.8) 
        var actionPath: IndexPath?
        var actionColor: UIColor?
        
        guard let visibleIndexPaths = indexPathsForVisibleRows else 
            return
        
        if #available(iOS 13.0, *) 
            // Use new API, UIContextualAction
            for path in visibleIndexPaths 
                if let config = delegate?.tableView?(self, trailingSwipeActionsConfigurationForRowAt: path), let action = config.actions.first 
                    actionPath = path
                    actionColor = action.backgroundColor
                    break
                
            
         else 
            for path in visibleIndexPaths 
                if let actions = delegate?.tableView?(self, editActionsForRowAt: path), let action = actions.first 
                    actionPath = path
                    actionColor = action.backgroundColor
                    break
                
            
        
        guard let path = actionPath, let cell = cellForRow(at: path) else  return 
        cell.presentTrailingSwipeHint(actionColor: actionColor ?? tintColor)
    


fileprivate extension UITableViewCell 
    func presentTrailingSwipeHint(actionColor: UIColor, hintWidth: CGFloat = 20, hintDuration: TimeInterval = 0.8) 
        // Create fake action view
        let dummyView = UIView()
        dummyView.backgroundColor = actionColor
        dummyView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(dummyView)
        // Set constraints
        NSLayoutConstraint.activate([
            dummyView.topAnchor.constraint(equalTo: topAnchor),
            dummyView.leadingAnchor.constraint(equalTo: trailingAnchor),
            dummyView.bottomAnchor.constraint(equalTo: bottomAnchor),
            dummyView.widthAnchor.constraint(equalToConstant: hintWidth)
        ])
        // This animator reverses back the transform.
        let secondAnimator = UIViewPropertyAnimator(duration: hintDuration / 2, curve: .easeOut) 
            self.transform = .identity
        
        // Don't forget to remove the useless view.
        secondAnimator.addCompletion  position in
            dummyView.removeFromSuperview()
        

        // We're moving the cell and since dummyView
        // is pinned to cell's trailing anchor
        // it will move as well.
        let transform = CGAffineTransform(translationX: -hintWidth, y: 0)
        let firstAnimator = UIViewPropertyAnimator(duration: hintDuration / 2, curve: .easeIn) 
            self.transform = transform
        
        firstAnimator.addCompletion  position in
            secondAnimator.startAnimation()
        
        // Do the magic.
        firstAnimator.startAnimation()
    

示例用法:

override func viewDidAppear(_ animated: Bool) 
    super.viewDidAppear(animated)
    tableView.presentSwipeHint()

【讨论】:

我只实现了删除,所以它通过直接从 tableView let cell = self.cellForRow(at: IndexPath(item: 0, section: 0)) 获取单元格对我有用,然后我必须在单元格上设置 clipsToBounds = false 以使 dymmyView 可见。 实际上(在 iOS 15.2 上测试),您必须设置 cell.clipsToBounds = false 才能使 dummyView 可见。【参考方案2】:

我很确定这是不可能的。滑动操作包含在UISwipeActionPullView 中,其中包含UISwipeStandardAction 子视图,它们都是私有的。它们也是表格视图的一部分,而不是单元格,除非发生手势,否则它们不会被添加,因此您不能只是将单元格撞到一侧并在那里看到它们。

在 UI 自动化测试之外,不使用私有 API 就无法模拟用户手势,因此您不能“伪造”滑动然后将结果显示给用户。

但是,既然可以作弊,为什么还要费心“正确”地去做呢?将单元格的内容视图稍微向左反弹应该不会太难,并在红色框中反弹(不要太远以至于您可以看到文本,以避免本地化问题),然后恢复正常。在第一次加载表格视图时执行此操作,并在 N 次或用户证明他们知道此特定 iOS 约定如何工作后停止执行此操作。

【讨论】:

有趣! ?我会检查一下。谢谢! 将暂时保留问题,以防其他想法也被泄露。不过我很感激! “什么时候可以作弊”似乎就是答案。这是一个视频,解释了如何:youtube.com/watch?v=oAGoFd_GrxE 感谢ios-developers.io slack iOS 社区的 jimc 分享。【参考方案3】:

首先:启用编辑

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

然后自定义您的滑动

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? 
   let conformeRowAction = UITableViewRowAction(style: UITableViewRowActionStyle.default, title: NSLocalizedString("C", comment: ""), handler:action, indexpath in
        print("C•ACTION")
    )
   conformeRowAction.backgroundColor = UIColor(red: 154.0/255, green: 202.0/255, blue: 136.0/255, alpha: 1.0)
   let notConform = UITableViewRowAction(style: UITableViewRowActionStyle.default, title: NSLocalizedString("NC", comment: ""), handler:action, indexpath in
        print("NC•ACTION")
    )
   notConform.backgroundColor = UIColor(red: 252.0/255, green: 108.0/255, blue: 107.0/255, alpha: 1.0)
   return [conformeRowAction,notConform]

【讨论】:

这不只会增加滑动显示动作的可能性吗?它并没有真正回答问题。 感谢您的宝贵时间,braham-youssef @andlin 是正确的。我正在寻找如何使用这个已经存在的滑动删除功能来玩 peekaboo,以便用户知道它存在。

以上是关于iOS - 如何查看表格视图单元格上的“滑动删除”操作?的主要内容,如果未能解决你的问题,请参考以下文章

在uitableview单元格上留下滑动删除按钮打开然后返回导致崩溃

表视图单元格上的 iOS 砌体

在 iOS 7 上的导航视图控制器上使用后退手势时,表格视图单元格上没有淡出和淡入动画

自定义表格视图单元格上的多个图像(Swift)

在表格视图中按下单元格上的按钮时如何创建新单元格

如何使表格视图单元格上的按钮调用正确的 tableView:cellForRowAtIndexPath?