Элемент добавляется в массив в одном контроллере представления, но не в другом - PullRequest
0 голосов
/ 03 мая 2020

У меня есть 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)
    }
}

Я посмотрел вокруг переполнения стека и другие сайты о добавлении в массивы, но по какой-то причине не могут понять, почему я не могу добавить массив в другой класс.

Ответы [ 2 ]

0 голосов
/ 03 мая 2020

Поскольку вы создали новый HomeController in NotesController , который не ссылается на ваш текущий 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)
}

Ответить на ваши вопросы .

  1. Из NotesController после сохранения вызывается. Вы ожидаете ["привет", "до свидания"], но вместо этого вы получаете ["до свидания"].

    • Поскольку вы создаете экземпляр HomeController в NotesViewController Созданный вами homeController не тот же HomeController отображается на экране, он новый, поэтому homeController и entryInput по-прежнему пустые, так как viewDidLoad не звоните.
  2. Когда вы добавляете другой элемент из NotesViewController , вы ожидаете ["до свидания", " до свидания "], но вместо этого вы получите [" до свидания "].

    • Согласно первому ответу. Вы создаете новый homeController (который не относится к существующему на экране) внутри NotesController каждый раз, когда он появляется на экране.

Вот результат.

  • Показ левого изображения HomeController .
  • Показ среднего изображения 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)
    }
}
0 голосов
/ 03 мая 2020

Это похоже на строку:

let homeController = HomeController()

создает новый экземпляр класса HomeController и не ссылается на уже существующий ViewController. Это означает: изменение массива в новом экземпляре HomeController не повлияет на ваш основной ViewController.

Это также приведет к ответу на ваш вопрос об отсутствующем элементе "hello" в вашем массиве. Когда вы создаете объект homeController, в его массиве нет элементов.

Когда вызывается @objc func save(sender: UIButton) get, вы добавляете "до свидания" к пустому массиву.

By calling dismiss(...) you возвращаются к исходной версии вашего HomeController(), который ничего не знает о другом экземпляре, который вы создали в NotesController().

Чтобы достичь того, что вы пытаетесь сделать, я рекомендую прочитать больше о том, как пройти данные между ViewControllers:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...