如何在prepare(for: segue)中使用SwipeCellKit的indexPath传递数据
解决SwipeCellKit滑动编辑按钮跳转时的Auto对象传递问题
问题场景
点击UITableView单元格行时,以下代码能正常将Auto对象传递到目标视图控制器:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { print(indexPath.row) performSegue(withIdentifier: "editAutoDetailsSegue", sender: self) } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "editAutoDetailsSegue" { print("Preparing to segue") let destinationVC = segue.destination as! EditAutoInfoViewController if let indexPath = tableView.indexPathForSelectedRow { print("Row Selected") destinationVC.selectedAuto = autombiles?[indexPath.row] } } }
但使用SwipeCellKit实现滑动显示编辑按钮后,点击编辑按钮执行segue时无法传递Auto对象。当前滑动操作的代码如下:
extension AutoViewController: SwipeTableViewCellDelegate { func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? { guard orientation == .right else { return nil } let deleteAction = SwipeAction(style: .destructive, title: "Delete") { action, indexPath in if let theAuto = self.autombiles?[indexPath.row] { do { try self.realm.write { self.realm.delete(theAuto) } } catch { print("There was an error deleting the auto \(error)") } } } let editAction = SwipeAction(style: .default, title: "Edit") { action, indexPath in self.performSegue(withIdentifier: "editAutoDetailsSegue", sender: self) } return [deleteAction, editAction] } func tableView(_ tableView: UITableView, editActionsOptionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions { var options = SwipeOptions() options.expansionStyle = .destructive options.transitionStyle = .border return options } }
核心原因
滑动点击编辑按钮时,单元格并未被选中,tableView.indexPathForSelectedRow会返回nil,导致无法获取对应的Auto对象。
解决方案
方案1:传递indexPath作为sender
修改编辑按钮的闭包,将当前的indexPath作为performSegue的sender参数:
let editAction = SwipeAction(style: .default, title: "Edit") { action, indexPath in self.performSegue(withIdentifier: "editAutoDetailsSegue", sender: indexPath) }
然后更新prepare(for:sender:)方法,同时处理两种sender类型:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "editAutoDetailsSegue" { print("Preparing to segue") let destinationVC = segue.destination as! EditAutoInfoViewController // 处理点击单元格的情况 if let indexPath = tableView.indexPathForSelectedRow { print("Row Selected") destinationVC.selectedAuto = autombiles?[indexPath.row] } // 处理滑动编辑按钮的情况 else if let indexPath = sender as? IndexPath { print("Swipe Edit Action Triggered") destinationVC.selectedAuto = autombiles?[indexPath.row] } } }
方案2:直接传递Auto对象(更简洁)
在编辑按钮闭包中直接获取对应的Auto对象并作为sender传递:
let editAction = SwipeAction(style: .default, title: "Edit") { action, indexPath in if let selectedAuto = self.autombiles?[indexPath.row] { self.performSegue(withIdentifier: "editAutoDetailsSegue", sender: selectedAuto) } }
然后更新prepare(for:sender:)方法,处理Auto类型的sender:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "editAutoDetailsSegue" { print("Preparing to segue") let destinationVC = segue.destination as! EditAutoInfoViewController // 处理点击单元格的情况 if let indexPath = tableView.indexPathForSelectedRow { print("Row Selected") destinationVC.selectedAuto = autombiles?[indexPath.row] } // 处理滑动编辑按钮的情况 else if let selectedAuto = sender as? Auto { print("Swipe Edit Action Triggered") destinationVC.selectedAuto = selectedAuto } } }
说明
两种方案都能解决问题,方案2更直接,减少了通过indexPath查找数据的步骤;方案1则保留了indexPath的灵活性,适合需要额外使用indexPath的场景。
内容的提问来源于stack exchange,提问作者Jon
相关产品推荐
相关产品推荐

