ios - TableView 连续并导致意外返回 nil

标签 ios swift uitableview storyboard segue

这是我当前的设置:

MainMenuViewController -> SubMenuViewController -> UserInputViewController -> ResultViewController

我的所有 View Controller 都包含一个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,但是当有更多选项时,需要实例化另一个SubMenuViewControllertableView 将根据用户之前点击的单元格自行填充,直到 selectedNode.isLeaveNode() 为 true(这意味着不会有任何子节点)。

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

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

它给我以下错误:

fatal error: unexpectedly found nil while unwrapping an Optional value

从我注册单元的地方开始:

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

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

有人能看出问题所在吗?

更新

这是我的其余代码:

UIViewController

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")
    }
}

UITableViewDataSource

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

    }
}

UITableViewDelegate

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

注意

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

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

相关文章:

ios - iTunes Connect 应用内购买定价未显示

ios - 如何在 UIView 之外读取 ApplePencil 压力数据?

arrays - 如果不存在则追加对象 swift

ios - 快速获取 iPhone 语言

ios - 从 customCell 按钮调用 TableView.m 中的操作

android - 使用不透明蒙版时图像的自动变换失败

ios - 如何对 drawRect 的自定义实现进行单元测试

ios - UITableViewCell 约束未更新

iphone - UITableViewCell 在排队时是否持有它的 View ? (用于 dequeueReusableCellWithIdentifier)

ios - Swift/NSMutableDisctionary init/如何使值可选