项目附加到一个视图控制器中的数组但不在另一个视图控制器中
Posted
技术标签:
【中文标题】项目附加到一个视图控制器中的数组但不在另一个视图控制器中【英文标题】:Item appends to array in one view controller but not in another 【发布时间】:2020-05-03 06:41:45 【问题描述】:我有一个在单元格中显示条目列表的 TableView。这些条目存储在一个数组中。用户在另一个视图控制器(模式)中为条目输入文本,点击“保存”,在.reloadData()
之后,新条目应附加到数组并显示在 TableView 中。该数组位于HomeController
中。
为了查明问题可能出在哪里,我尝试在HomeController
中附加一些文本,然后从NotesController
附加到同一个数组。在后者中,当我打印homeController.entryInput
时,我期待["hello", "goodbye"]
。相反,我只得到["goodbye"]
。
另外,当我再次点击NotesController
中的“保存”时,我再次得到["goodbye"]
而不是["goodbye", "goodbye"]
。所以看起来数组被覆盖了。
我还尝试将项目硬编码到数组中,它们在 TableView 中显示良好。当我从NotesController
追加一个项目时,它会追加到数组但不会显示在 TableView 上,当我从同一个 ViewController 添加另一个项目时,它会覆盖我附加的第一个项目,而不是将其添加为新项目.
HomeController:
class HomeController: UIViewController
let tableView = UITableView()
var entryInput: [String] = []
override func viewDidLoad()
super.viewDidLoad()
setupTableView()
func setupTableView()
tableView.delegate = self
tableView.dataSource = self
self.entryInput.append("hello")
print(entryInput)
tableView.register(HomeCell.self, forCellReuseIdentifier: reuseIdentifier)
let height = view.frame.height
tableView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: height)
tableView.backgroundColor = .white
view.addSubview(tableView)
extension HomeController: UITableViewDelegate, UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return entryInput.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = self.tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! HomeCell
cell.entryTextLabel.text = entryInput[indexPath.row]
return cell
NotesController:
class NotesController: UIViewController
let homeController = HomeController()
...
let saveBtn = UIView().navigationBtn(text: "Save")
let homeController = HomeController()override func viewDidLoad()
super.viewDidLoad()
view.backgroundColor = .white
saveBtn.addTarget(self, action: #selector(save(sender:)), for: .touchUpInside)
@objc func save(sender: UIButton)
homeController.entryInput.append("goodbye")
homeController.tableView.reloadData()
print(homeController.entryInput)
dismiss(animated: true, completion: nil)
我查看了 Stack Overflow 和其他有关附加到数组的网站,但由于某种原因,我似乎无法弄清楚为什么我不能附加到另一个类中的数组。
【问题讨论】:
在 HomeController 类的 viewDidLoad 中添加 log 并检查它是否被调用。 可能是你有多个 HomeViewController。因此,当您从 NotesController 将数据附加到 HomeViewController 时,它是一个新实例。 NotesController 是您说的主要 VC 还是 modal? 【参考方案1】:因为您在 NotesController 中创建了新的 HomeController,它不引用您当前的 HomeController.
class NotesController: UIViewController
let homeController = HomeController()
当HomeController想要打开NotesController时。 NotesController 想要与 HomeController 进行通信。 您应该将 HomeController 引用传递给 NotesController。
func routeToNotesController()
let vc = NotesViewController()
vc.homeController = self
let nc = UINavigationController(rootViewController: vc)
present(nc, animated: true)
回答您的问题。
保存后从 NotesController 调用。你期待 ["hello","goodbye"] 但你得到的是 ["goodbye"]。
因为您正在实例化 HomeController NotesViewController 您创建的 homeController 不是 同样的 HomeController 出现在屏幕上,它是新的所以 homeController 和 entryInput 仍然为空,因为 viewDidLoad 不是 打电话。当您从 NotesViewController 添加另一个项目时,您将 期待 ["goodbye", "goodbye"] 但你却得到 ["goodbye"]。
根据第一个答案。你创建了新的 homeController(那不是 NotesController 内与屏幕上现有的相关联 每次出现在屏幕上。这是结果。
左图显示 HomeController。 中间图像显示打开 InputsController 的 HomeController。 右图显示由 InputsController 更新的 HomeController。我的实现。
class ListViewController: UITableViewController
var entryInput: [String] = []
override func viewDidLoad()
super.viewDidLoad()
navigationItem.title = "ListViewController"
tableView.backgroundColor = .white
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(add))
entryInput.append("hello")
tableView.reloadData()
@objc func add()
let vc = InputViewController()
vc.listViewController = self
let nc = UINavigationController(rootViewController: vc)
present(nc, animated: true)
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return entryInput.count
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = entryInput[indexPath.row]
return cell
class InputViewController: UIViewController
weak var listViewController: ListViewController?
override func viewDidLoad()
super.viewDidLoad()
navigationItem.title = "InputViewController"
view.backgroundColor = .white
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(save))
@objc func save()
listViewController?.entryInput.append("goodbye")
listViewController?.tableView.reloadData()
dismiss(animated: true)
【讨论】:
非常感谢您的示例和详细的回答。我理解为什么是 vc,虽然我在我的陈述中不够清楚,当 NotesController 出现时,它已经被推送到一堆视图中。当用户点击“添加”时,堆栈中的第一个以模态方式呈现并嵌入到 NavController 中,用户单击 VC 直到最后一个,NotesController,当用户点击“保存”时,它会被关闭。我能做些什么呢?【参考方案2】:看起来像一行:
let homeController = HomeController()
创建HomeController
类的新实例,并且不引用已经存在的 ViewController。这意味着:在 HomeController
的新实例中修改数组不会影响您的主 ViewController。
这也可以回答您关于数组中缺少“hello”元素的问题。当您创建对象homeController
时,它的数组没有任何元素。
当@objc func save(sender: UIButton)
被调用时,您将“再见”附加到空数组。
通过calling dismiss(...)
,您将返回到HomeController()
的原始版本,它对您在NotesController()
中创建的其他实例一无所知。
为了实现你想要做的事情,我建议阅读更多关于如何在 ViewControllers 之间传递数据:
How do you share data between view controllers and other objects in Swift? https://www.hackingwithswift.com/example-code/system/how-to-pass-data-between-two-view-controllers【讨论】:
以上是关于项目附加到一个视图控制器中的数组但不在另一个视图控制器中的主要内容,如果未能解决你的问题,请参考以下文章
如何以模态方式将视图添加到不在视图层次结构中的另一个视图 iOS
如何在我的 Xcode Swift 项目的不同导航堆栈中从一个视图控制器屏幕切换到另一个?