【问题标题】:TableView seguing and cause unexpectedly nil returnedTableView seguing 并导致意外返回 nil
【发布时间】:2018-02-03 20:46:15
【问题描述】:

这是我目前的设置:

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

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

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

它给了我以下错误:

致命错误:在展开可选值时意外发现 nil

从我在这里注册我的单元格的地方:

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

    }  
}

【问题讨论】:

  • 你的subMenuViewController 被实例化了吗?如果您在let 之后立即打印,您会得到什么?
  • 请添加您的 SubMenuViewController 初始化代码。
  • 请看更新,谢谢
  • @BrendonCheung 您在哪个确切的代码通道上发现了崩溃?这个插座@IBOutlet weak var tableView: UITableView! 是否与故事板连接?你用prepareForSegue:函数吗?
  • @VasiliiMuravev 错误在tableView.register(nib, forCellReuseIdentifier: "SubMenuCell"),是的,我的tableView 是连接的,不,我没有使用prepareForSegue。考虑到这一点,我们不能使用prepareForSegue,因为故事板中没有segue。 SubMenuViewController 实例化自己

标签: ios swift uitableview storyboard segue


【解决方案1】:

在您的 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()

【讨论】:

  • 谢谢,奇怪的是当MainMenuViewController 转入SubMenuViewController 时,一切正常!但是一旦我尝试实例化同一个控制器(SubMenuViewController),它就会失败。我试过你的方法,错误仍然存​​在
  • 我在 tableView:cellForRowAtIndexPath 重新加载 tableView 的委托方法中添加了额外的一行。试试看。
【解决方案2】:

问题解决了

问题在于我错误地实例化了我的视图控制器。行:

let subMenuViewController = SubMenuViewController(node: selectedNode)

只返回一个没有出口的原始对象,这就是为什么我得到可选的 nil 错误,因为没有 tableView 可以开始。

正确的方法是使用情节提要对其进行实例化。每个视图控制器都有一个可选的故事板属性,因为我的视图控制器存在于故事板中,所以该属性不会为 nil。

不要这样做:

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

我实际上需要这样做:

let subMenuViewController = storyboard!.instantiateViewController("SubMenuViewController") 

这样我就确定我的 subMenuViewController 将包含我的 tableView 属性,它是来自故事板的 IBOutlet。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多