这是我当前的设置:

MainMenuViewController-> SubMenuViewController-> UserInputViewController-> ResultViewController

我所有的视图控制器都包含一个tableView

当用户点击MainMenuViewControlle中的单元格时,它将选择到SubMenuViewController。一切都很好。

在这里很棘手,在SubMenuViewController中,需要实例化另一个SubMenuViewController的单元格,因为子菜单选项可能深达数个级别。

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

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

        if selectedNode.isLeaveNode() {
            performSegue(withIdentifier: "userInput", sender: self)
        } else {
            let subMenuViewController = SubMenuViewController(node: selectedNode)
            self.navigationController?.pushViewController(subMenuViewController, animated: true)
        }


当没有子节点时,它将选择到UserInputViewController,但是当有更多选项时,它需要实例化另一个SubMenuViewController,并且tableView将根据用户之前点击的单元格填充自身,直到是正确的(这意味着将没有任何子节点)。

这个问题是当这段代码运行时:

    let subMenuViewController = SubMenuViewController(node: selectedNode)
    self.navigationController?.pushViewController(subMenuViewController, animated: true)


它给我以下错误:


  致命错误:解开Optional值时意外发现nil


从这里我注册我的单元格的位置是:

let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: "SubMenuTableViewCell", bundle: bundle)
tableView.register(nib, forCellReuseIdentifier: "SubMenuCell")


我的所有tableView单元格都使用xib文件实例化,并且我已经在selectedNode.isLeaveNode()中注册了单元格

有人可以看到问题吗?

更新

这是我其余的代码:

viewDidLoad()

class SubMenuViewController: UIViewController {

    var node: Node?

    init(node: Node) {
        self.node = node
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {

        super.viewDidLoad()

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

        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: "SubMenuTableViewCell", bundle: bundle)
        tableView.register(nib, forCellReuseIdentifier: "SubMenuCell")
    }
}


UIViewController

extension SubMenuViewController: UITableViewDataSource {

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

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

        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

    }
}


UITableViewDataSource

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

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

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

        if selectedNode.isLeaveNode() {
            performSegue(withIdentifier: "userInput", sender: self)
        } else {
            let subMenuViewController = SubMenuViewController(node: selectedNode)
            self.navigationController?.pushViewController(subMenuViewController, animated: true)
        }

    }
}

最佳答案

在您的viewDidLoad()方法中,请确保执行以下操作:

根据您发布的代码,此行可能存在问题:

let bundle = Bundle(for: type(of: self))


我建议将其替换为以下行:

let bundle = Bundle(forClass: self)


要么

let bundle = Bundle.main


如果您仍然遇到问题,请尝试修改以下代码行:

let nib = UINib(nibName: "SubMenuTableViewCell", bundle: bundle)




let nib = UINib(nibName: "SubMenuTableViewCell", bundle: nil)


在您的tableView:cellForRowAtIndexPath UITableViewControllerDelegate方法中,包括以下几行:

var cell = tableView.dequeueReusableCellWithIdentifier("SubMenuCell") as? UITableViewCell

if cell == nil {
    tableView.registerNib(UINib(nibName: "SubMenuTableViewCell", bundle: nil), forCellReuseIdentifier: "SubMenuCell")
    cell = tableView.dequeueReusableCellWithIdentifier("SubMenuCell") as SubMenuTableViewCell!
}

cell.configure(data: data[indexPath.row])
tableView.reloadData()
return cell


注意


确保UITableViewCell的reuseIdentifier为“ SubMenuCell”
确保SubMenuTableViewCell.xib文件的所有者为SubMenuTableViewCell
确保模块不说“无”(即模块应该是项目目标的名称)。
确保在tableView.reloadData()函数中调用viewDidLoad()

关于ios - TableView隔离并导致意外返回nil,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45887523/

10-12 04:21