Ios 如何实施Peek&;通过代码手动弹出表格特定行的功能? 目标

Ios 如何实施Peek&;通过代码手动弹出表格特定行的功能? 目标,ios,swift,uitableview,force-touch,Ios,Swift,Uitableview,Force Touch,我正在尝试将“偷看和弹出”功能添加到我的表行中 您无法从tableview中获取单元格。因此,步骤如下: 使用UIViewControllerPreviewingDelegate方法中的位置点获取indexPath 使用indepath从tableView获取单元格 获取单元格后,将单元格框架转换为tableview框架 将帧作为sourceRect指定给previewingContext 代码如下: 在视图中加载 if self.traitCollection.forceTouchCapab

我正在尝试将“偷看和弹出”功能添加到我的表行中



您无法从tableview中获取单元格。因此,步骤如下:

  • 使用
    UIViewControllerPreviewingDelegate
    方法中的位置点获取
    indexPath
  • 使用
    indepath
    tableView
    获取单元格
  • 获取单元格后,将单元格框架转换为tableview框架
  • 将帧作为sourceRect指定给
    previewingContext
  • 代码如下:

    视图中加载

    if self.traitCollection.forceTouchCapability == .available {
        registerForPreviewing(with: self, sourceView: tableView)
    }
    
    进一步说:

    extension ProfileViewController: UIViewControllerPreviewingDelegate {
    
        func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
            if let indexPath = tableView.indexPathForRow(at: location), let cell = tableView.cellForRow(at: indexPath) {
                previewingContext.sourceRect = tableView.convert(cell.frame, to: self.tableView)
                guard let detailViewController = storyboard?.instantiateViewController(withIdentifier: "profileDetail") as? ProfileDetailViewController else {
                    return nil
                }
                return detailViewController
            }
            return nil
        }
    
        func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
            self.navigationController?.pushViewController(viewControllerToCommit, animated: true)
        }
    }
    

    通常,我使用一个简单的单元格扩展来实现这一点:

    class ForceTouchCell: UITableViewCell {
        var previewingContext: UIViewControllerPreviewing?
    
        func registerPreview(on controller: UIViewController, with delegate: UIViewControllerPreviewingDelegate) {
            self.previewingContext = controller.registerForPreviewing(with: delegate, sourceView: self)
        }
    
        func unregisterPreview(on controller: UIViewController) {
            guard let previewingContext = previewingContext else {
                return
            }
    
            controller.unregisterForPreviewing(withContext: previewingContext)
            self.previewingContext = nil
        }
    }
    
    然后在控制器上:

    class MyController: UIViewController, UITableViewDelegate {
        var tableView: UITableView!
    
        override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
            guard traitCollection.forceTouchCapability != previousTraitCollection?.forceTouchCapability else {
                return
            }
    
            let visibleCells = tableView.visibleCells
                   .compactMap { $0 as? ForceTouchCell }
    
            if traitCollection.forceTouchCapability == .available {
               visibleCells.forEach {
                   $0.registerPreview(on: self, with: self)
               }
            } else {
               visibleCells.forEach {
                   $0.unregisterPreview(on: self)
               }
            }
        }
    
        func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
            if let forceTouchCell = cell as? ForceTouchCell {
                if self.traitCollection.forceTouchCapability == .available {
                    forceTouchCell.registerPreview(on: self, with: self)
                }
             }
        }
    
        func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
            if let forceTouchCell = cell as? ForceTouchCell {
                forceTouchCell.unregisterPreview(on: self)
            }
        }
    }
    
    extension MyConroller: UIViewControllerPreviewingDelegate {
        func previewingContext(
        _ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint
    ) -> UIViewController? {
        guard
            let cell = (previewingContext.sourceView as? ForceTouchCell),
            let indexPath = tableView.indexPath(for: cell)
        else {
            return nil
        }
    
        // use the indexPath/cell to create preview controller
    }
    

    此解决方案的好处在于,它可以轻松地在控制器之间共享,例如使用带有默认实现的协议。

    您是否在
    previewingContext(\uPreviewingContext:UIViewControllerPreviewing,viewControllerForLocation:CGPoint)
    方法中设置了断点?它叫什么名字?它是否返回视图控制器?你在测试什么设备?集合视图控制器是在您当前的VC上还是在细节VC上?这看起来是一个很好的解决方案:您发布的错误似乎与您的问题无关。-1,即使是苹果公司也有一个适当的示例应用程序来展示peek'n'pop的实现:如果您除了返回它之外没有使用
    detailViewController
    ,您可以摆脱
    保护
    ,只需执行
    返回情节提要?。实例化eviewController(带有标识符:“profileDetail”)作为?ProfileDetailViewController
    ,它将与您当前的代码等效,但更短、更简单此解决方案的问题是您没有注册单元格本身,因此在按下单元格时,不会在单元格周围显示动画边框。