我正在尝试从另一个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,我不知道它是否因此而无法工作。
答案 0 :(得分:3)
如果在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
}
}
}
答案 1 :(得分:1)
performSegue
将创建ShowIssueDetail
的新实例。
因此,您从未设置idSelected
答案 2 :(得分:1)
您似乎在谈论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
}
}
答案 3 :(得分:1)
您的方法在这里是错误的:
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上相同的所选属性。