【问题标题】:How to open a navigation controller with the title of the cell selected如何打开带有选定单元格标题的导航控制器
【发布时间】:2019-04-20 01:04:30
【问题描述】:

我希望在选择表格单元格时打开导航控制器。导航控制器必须具有所选单元格中包含的文本的标题。

我认为我的代码非常接近,但似乎无法弄清楚我做错了什么。

当我从表格中选择一个单元格时,什么都不会打开。

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

        // Retrieve cell
        let cellIdentifier: String = "stockCell"
        let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
        myCell.textLabel?.textAlignment = .center
        myCell.textLabel?.font = .boldSystemFont(ofSize: 18)
        // Get the stock to be shown
        let item: StockModel = feedItems[indexPath.row] as! StockModel
        // Configure our cell title made up of name and price


        let titleStr = [item.customer].compactMap { $0 }.joined(separator: "-")


        print(titleStr)
        // Get references to labels of cell
        myCell.textLabel!.text = titleStr

        return myCell
    }

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

        let item: StockModel = feedItems[indexPath.row] as! StockModel
        let titleStr = [item.customer].compactMap { $0 }.joined(separator: "-")

        print(titleStr)

    }

     func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "customerDetails" {

        let destinationVC = segue.destination as UIViewController
        let cellIdentifier: String = "stockCell"
        let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
        destinationVC.navigationItem.title = myCell.textLabel!.text
        }
    }

}

新更新:

以下现在有效:

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


    let cellIdentifier: String = "stockCell"
    let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
    myCell.textLabel?.textAlignment = .center

    // Get the stock to be shown
    let item: StockModel = feedItems[indexPath.row] as! StockModel
    // Configure our cell title made up of name and price

    let titleStr = [item.customer].compactMap { $0 }.joined(separator: "-")

    print(titleStr)
    // Get references to labels of cell
    myCell.textLabel!.text = titleStr

    let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "detailController")
    controller.title = titleStr
    navigationController?.pushViewController(controller, animated: true)

}

但我需要视图控制器将自己呈现为 Show Detail 故事板样式,其中 detailController 覆盖 FirstViewController。

你不能回去的地方。

【问题讨论】:

标签: ios swift uitableview


【解决方案1】:

检查是否在 main.storyboard 文件中连接了 segue。如果是,请检查标识符是否与代码中的标识符匹配。如果这不起作用,可能是因为您在 prepareForSegue 中创建了一个新单元格,并且要解决此问题,您必须为每个单元格创建一个全局变量。如果所有这些都不起作用,请告诉我。能否附上 main.storyboard 文件。

【讨论】:

  • 我不确定如何创建全局变量,但其他一切都正确。我认为我错误地传递了单元格值(单元格中的文本)
【解决方案2】:

您应该在 deistinationVC 中使用 variable,然后在 ViewDidLoad 中使用“navigationItem.title”

firstViewController中:

func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "customerDetails" {

    let destinationVC = segue.destination as UIViewController
    let cellIdentifier: String = "stockCell"
    let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
    destinationVC.navTitle = myCell.textLabel!.text
    }
}

SecondViewController

class secondViewcontroller : UIViewController{

  var navTitle = string()

  override func viewDidLoad() {

    navigationItem.title = navTitle

   }

【讨论】:

  • 不要忘记在 distinationVC 中定义“var navTitle = string()”
  • 使用推送导航>> let vc = storyboard?.instantiateViewController(withIdentifier: "customerDetails") as!客户详细信息VC 。和 >> vc.navTitle = titleStr 和 >> navigationController?.pushViewController(vc, animated: true)
【解决方案3】:

在这种情况下,最好仅以编程方式推送视图控制器。一个极其简单的完整示例如下所示:

class ViewController: UIViewController {

    let titles: [String] = ["First", "Second", "Third"]

    override func viewDidLoad() {
        super.viewDidLoad()
    }

}

// MARK: - UITableViewDelegate, UITableViewDataSource

extension ViewController: UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return titles.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
        cell.textLabel?.text = titles[indexPath.row]
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let controller = UIViewController() // or UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "whateverIdentifierISetInStoryboard")
        controller.title = titles[indexPath.row]
        navigationController?.pushViewController(controller, animated: true)
    }

}

所以使用navigationController?.pushViewController(controller, animated: true) 是一种方法,它会显示一个从右到左动画的新视图控制器。

标题直接在视图控制器上设置,可以使用UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "whateverIdentifierISetInStoryboard")从情节提要创建。

这假设这个视图控制器实际上已经在导航控制器上。

如果您确实需要使用 segue 执行此操作,则需要使用标识符手动调用 segue。您还可以将标题作为sender 参数发送。

self.performSegue(withIdentifier: "customerDetails", sender: titles[indexPath.row])

在你的情况下可能是这样的:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let item: StockModel = feedItems[indexPath.row] as! StockModel
    let titleStr = [item.customer].compactMap { $0 }.joined(separator: "-")
    self.performSegue(withIdentifier: "customerDetails", sender: titleStr)
}

现在只需使用这个标题:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "customerDetails" {
        let destinationVC = segue.destination as UIViewController
        destinationVC.title = sender as? String
    }
}

另一种方法是将当前标题保存在属性上,然后在准备 segue 时使用它:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let item: StockModel = feedItems[indexPath.row] as! StockModel
    let titleStr = [item.customer].compactMap { $0 }.joined(separator: "-")
    self.nextScreenTitle = titleStr
    self.performSegue(withIdentifier: "customerDetails", sender: self)
}

然后用法:

var nextScreenTitle: String?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "customerDetails" {
        let destinationVC = segue.destination as UIViewController
        destinationVC.title = nextScreenTitle
    }
}

【讨论】:

  • 我没有收到任何错误,但标题只是没有显示在导航控制器标题中
  • @RelsonJames 我道歉。 prepareForSegue 方法已在最新的 Swift 中重命名。请检查我更新的答案。你需要使用override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  • 还是不显示,会不会是单元格中的文字没有正确传递?
  • @RelsonJames 您的字符串有可能是nil 或空的。尝试确认这一点。我建议你在prepare(for segue 中放置一个断点(你在一行中按下代码的左边,应该会显示一个蓝色项目符号)。当您运行项目时,它应该停在该行并且您可以检查所有值。此外,此时您可以使用控制台(Xcode 的右下部分)打印您可以访问的值。您通常使用“po”来打印您的对象。在您的情况下,请尝试“po sender as?String”。这应该给你你创建的字符串。如果为 nil,请在 performSegue 处检查。
  • 发件人:titleStr 在 performSegue 中正确定义,但在 destinationVC.tlte = sender as 中为 nil?字符串
【解决方案4】:

在您的更新版本中执行此操作

let controller = storyboard.instantiateviewcontroller(withIdentifier: "youridentifier") as? "name of your view controller"
navigationController?.present(controller, animated: true, completion: nil)

【讨论】:

    猜你喜欢
    • 2022-01-01
    • 2017-05-14
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-08
    • 1970-01-01
    • 2011-11-30
    相关资源
    最近更新 更多