如何将indexPath值从performSegue()传递给prepareForSegue()

时间:2017-08-30 03:58:15

标签: ios swift tableview

我在SubMenuViewController中有一个tableView,当用户在一个单元格上点击(使用didSelectRowAt)并进行segues时,我需要将该单元格传递给下一个UserInputViewController

这是我的代码:

class SubMenuViewController: UIViewController {

    //MARK: - Properties and outlets

    var node: Node?
    @IBOutlet weak var tableView: UITableView!

    //MARK: - View controller methods

    override func viewDidLoad() {

        super.viewDidLoad()

        self.navigationController?.isNavigationBarHidden = false
        self.navigationItem.title = node?.value.rawValue

        let nib = UINib(nibName: "SubMenuTableViewCell", bundle: nil)
        tableView.register(nib, forCellReuseIdentifier: "SubMenuCell")
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "userInput" {
            let vc = segue.destination as! UserInputViewController
            let indexPath = sender as! IndexPath
            vc.node = node?.childenNode[indexPath.row]
        }
    }
}

//MARK: UITableViewDataSource methods

extension SubMenuViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return node!.childCount
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "SubMenuCell", for: indexPath) as! SubMenuTableViewCell
        let desciptionModule = node?.childenNode[indexPath.row].value

        let description = Modules.description(module: desciptionModule!)

        cell.title.text = description.main
        cell.subtitle.text = description.sub

        return cell
    }
}

//MARK: - UITableViewDelegate methods

extension SubMenuViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 68
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        tableView.deselectRow(at: indexPath, animated: true)

        guard let selectedNode = node?.childenNode[indexPath.row] else {
            return
        }

        if selectedNode.isLeaveNode() {
            performSegue(withIdentifier: "userInput", sender: indexPath)
        } else {
            let subMenuViewController = self.storyboard!.instantiateViewController(withIdentifier: "subMenu") as! SubMenuViewController
            subMenuViewController.node = selectedNode
            //let subMenuViewController = SubMenuViewController(node: selectedNode)
            self.navigationController?.pushViewController(subMenuViewController, animated: true)
        }
    }
}

现在,在我的performSegue中,我将indexPath传递给发件人,我希望能够在prepareForSegue中找回来,但我不能。有什么建议吗?

由于

1 个答案:

答案 0 :(得分:2)

我的意见中,将索引路径(或任何其他计算s“数据”的值)作为sender参数传递是不太好的做法;顾名思义,它用于传递发送消息的对象(即,称为动作方法),在这种情况下self(如果你的动作方法调用另一个动作方法,你可以“转发”原始发送者相反,但这是偏离主题的。)

正如@sCha在评论中所指出的那样,特别是关于这种方法的Apple文档似乎仍然存在疑问。参数名称发送者显然来自遵循Cocoa目标/行动模式的所有控制行为中的同名参数。

我的建议:

我认为您可以做的最好的事情是在视图控制器的属性存储索引路径:

var selectedIndexPath: IndexPath? 
tableView(_:didSelectRowAt:)

... 设置

if selectedNode.isLeaveNode() {
    self.selectedIndexPath = indexPath
    performSegue(withIdentifier: "userInput", sender: indexPath)
} else {
    self.selectedIndexPath = nil
    // ...
在目标视图控制器的prepareForSegue(_:sender:)实现中

...和检索(重置属性时):

if let vc = segue.source as? SubmenuViewController {
    if let indexPath = vc.selectedIndexPath {
        vc.selectedIndexPath = nil // (reset it, just to be safe)

        // Use indexPath...
    }    
}