如何打开相同的视图控制器实例?
How do I open same instance of view controller?
我试图在每次单击 tableview 单元格时打开同一个 tableview 实例,但我得到的只是一个新创建的视图。例如,当我去 "CounterViewController" 并使用计数器时,当我稍后返回时,计数器又回到零。
这是我目前用于实例化视图控制器的代码。
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "TimerViewController") as! TimerViewController
self.present(vc, animated: true, completion: nil)
}
if indexPath.row == 1 {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "DateViewController") as! DateViewController
self.present(vc, animated: true, completion: nil)
}
if indexPath.row == 2 {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "CounterViewController") as! CounterViewController
self.present(vc, animated: true, completion: nil)
}
}
我要注意,我使用的是导航视图控制器,当我使用这种方法时,它也没有在传递给 tableview 控制器的视图控制器顶部显示导航栏。
如果需要更多信息才能正确回答这个问题,请告诉我。谢谢。
正如其他人指出的那样,每次 select 一个单元格时,您的代码都使用 instantiateViewController(withIdentifier:)
创建视图控制器 class 的新实例。根据定义,您每次这样做都会得到一个新单元格。
相反,创建一个 Optional
填充了 nil
的视图控制器数组,并使用它来获取所需的视图控制器。如果存在,请使用它。如果没有,请创建它并将其保存在您的数组中:
//Create an array of view controller identifiers to use to create VCs
let identifiers = ["TimerViewController", "DateViewController", "CounterViewController"]
//Create an array of [UIViewController?] and populate it with nil values
var viewControllers: [UIViewController?] = Array(repeating: nil, count: identifiers.count)
然后为您的索引创建一个 return 视图控制器的函数。像这样:
func viewControllerAt(index: Int) -> UIViewController {
guard index < viewControllers.count else {
fatalError("index out of range!")
}
var result = viewControllers[index] //try to fetch a VC from the array
//if it's nil, create a VC using the correct identifier and save it to the array
if result == nil {
result = InstantiateViewController(withIdentifier: identifiers[index]
viewControllers[index] = result
}
return result
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = viewControllerAt(indexPath.row)
self.present(vc, animated: true, completion: nil)
}
请注意,我回答了您问题的 "letter":每次点击单元格时如何显示相同的视图控制器实例。
正如 Matt 指出的那样,最好创建一个状态数据数组,并像现在一样在每次点击时创建视图控制器的新实例,但使用保存的状态填充新的子视图控制器该行的数据。这是非常普遍的,它有一个名字:master/detail 设计模式,甚至有系统支持它。尝试搜索 iOS master/detail 设计模式以获取更多信息。
我试图在每次单击 tableview 单元格时打开同一个 tableview 实例,但我得到的只是一个新创建的视图。例如,当我去 "CounterViewController" 并使用计数器时,当我稍后返回时,计数器又回到零。
这是我目前用于实例化视图控制器的代码。
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "TimerViewController") as! TimerViewController
self.present(vc, animated: true, completion: nil)
}
if indexPath.row == 1 {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "DateViewController") as! DateViewController
self.present(vc, animated: true, completion: nil)
}
if indexPath.row == 2 {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "CounterViewController") as! CounterViewController
self.present(vc, animated: true, completion: nil)
}
}
我要注意,我使用的是导航视图控制器,当我使用这种方法时,它也没有在传递给 tableview 控制器的视图控制器顶部显示导航栏。
如果需要更多信息才能正确回答这个问题,请告诉我。谢谢。
正如其他人指出的那样,每次 select 一个单元格时,您的代码都使用 instantiateViewController(withIdentifier:)
创建视图控制器 class 的新实例。根据定义,您每次这样做都会得到一个新单元格。
相反,创建一个 Optional
填充了 nil
的视图控制器数组,并使用它来获取所需的视图控制器。如果存在,请使用它。如果没有,请创建它并将其保存在您的数组中:
//Create an array of view controller identifiers to use to create VCs
let identifiers = ["TimerViewController", "DateViewController", "CounterViewController"]
//Create an array of [UIViewController?] and populate it with nil values
var viewControllers: [UIViewController?] = Array(repeating: nil, count: identifiers.count)
然后为您的索引创建一个 return 视图控制器的函数。像这样:
func viewControllerAt(index: Int) -> UIViewController {
guard index < viewControllers.count else {
fatalError("index out of range!")
}
var result = viewControllers[index] //try to fetch a VC from the array
//if it's nil, create a VC using the correct identifier and save it to the array
if result == nil {
result = InstantiateViewController(withIdentifier: identifiers[index]
viewControllers[index] = result
}
return result
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = viewControllerAt(indexPath.row)
self.present(vc, animated: true, completion: nil)
}
请注意,我回答了您问题的 "letter":每次点击单元格时如何显示相同的视图控制器实例。
正如 Matt 指出的那样,最好创建一个状态数据数组,并像现在一样在每次点击时创建视图控制器的新实例,但使用保存的状态填充新的子视图控制器该行的数据。这是非常普遍的,它有一个名字:master/detail 设计模式,甚至有系统支持它。尝试搜索 iOS master/detail 设计模式以获取更多信息。