繁体   English   中英

变量从另一个swift文件更改其值后返回nil值

[英]Variable returns nil value after changing its value from another swift file

我正在尝试从另一个Swift文件中更改变量的值,但是由于某些原因,它不起作用并且返回nil。

这是我尝试过的:

class ShowIssues: UIViewController, UITableViewDataSource, UITableViewDelegate {
  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let si = self.storyboard?instantiateViewController(withIdentifier: "ShowIssueDetail") as! ShowIssueDetail
    si.idSelected = indexPath.row //Here I change the value of the variable
    performSegue(withIdentifier: "ShowIssueDetail", sender: self)
  }
}

ShowIssueDetail.swift:

class ShowIssueDetail: UITableViewController {
  var idSelected: Int! //This is the variable I want to change its value from the another swift file
    override func viewDidLoad() {
      print(idSelected) //Here it prints out nil instead of the selected row
    }
}

我也以这种方式尝试过,但存在相同的问题:

class ShowIssues: UIViewController, UITableViewDataSource, UITableViewDelegate {
  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let si = ShowIssueDetail()
    si.idSelected = indexPath.row //Here I change the value of the variable
    performSegue(withIdentifier: "ShowIssueDetail", sender: self)
  }
}

我究竟做错了什么?

先感谢您!

注意:两个swift文件的类型不同,ShowIssues.swift是UIViewController,ShowIssueDetail是UITableViewController,我不知道它是否因此不起作用。

如果在Storyboard中设置了segue,则不应从代码实例化目标视图控制器,Storyboard会为您创建视图控制器。 通过初始化另一个实例,您最终将在一个实例中设置值,而该值不会显示给用户。

您需要覆盖prepare(for:)并在那里设置值。

class ShowIssues: UIViewController, UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        performSegue(withIdentifier: "ShowIssueDetail", sender: indexPath.row)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "ShowIssueDetail", let destinationVC = segue.destination as? ShowIssueDetail, let selectedId = sender as? Int {
          destinationVC.idSelected = selectedId
        }
    }
}

performSegue将创建ShowIssueDetail的新实例。

因此,您永远不会设置idSelected

您似乎在谈论ShowIssueDetail视图控制器中的变量idSelected。

问题在于,在两个版本的代码中,您创建的视图控制器实例都与要查找的实例不同,并在该视图控制器中设置了值。

您需要使用prepareForSegue将该变量传递到您要选择的视图控制器。

//Add an instance variable to remember which item is selected.
var selected: Int? 

class ShowIssues: UIViewController, UITableViewDataSource, UITableViewDelegate {
  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    selected = self.storyboard?instantiateViewController(withIdentifier: "ShowIssueDetail") as! ShowIssueDetail
    performSegue(withIdentifier: "ShowIssueDetail", sender: self)
  }
}

func prepare(for: segue, sender: Any) {
   if let dest = segue.destination as? ShowIssueDetail {
     dest.idSelected = selected
   }
}

您的方法在这里是错误的:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let si = self.storyboard?instantiateViewController(withIdentifier: "ShowIssueDetail") as! ShowIssueDetail
    si.idSelected = indexPath.row //Here I change the value of the variable
    performSegue(withIdentifier: "ShowIssueDetail", sender: self)
}

您正在创建VC的另一个实例并设置该值。 该VC不是将要显示的实际VC。

您需要使用prepareForSegue方法

var selectedRow: someTypeSameAsRow?

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    selectedRow = indexPath.row
    performSegue(withIdentifier: "ShowIssueDetail", sender: self)
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "ShowIssueDetail",
        let vc = segue.destination as? ShowIssueDetail {
        vc.idSelected = selectedRow
    }
}

编辑:

要解决注释中提到的错误,您可能需要做的就是等待详细视图正确加载。 awakeFromNib函数应该在这里工作:

// this goes in the view controller
override func awakeFromNib() {
    super.awakeFromNib()

    self.detailView.selected = selected
}

因此,使用此代码,您将等到VC视图及其子视图完全加载后,再将showDetailView的selected属性设置为与VC上相同的selected属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM