Как передать данные обратно контроллеру представления в стеке? - PullRequest
0 голосов
/ 27 июня 2018

Я видел много вопросов в этой категории, но все они, кажется, отвечают одинаково, то есть просто передают данные между viewcontrollers, а это не то, что, я думаю, я ищу.

У меня есть VC1, в котором хранятся данные, при определенных обстоятельствах пользователю нужна вся информация в VC2. Мне нужно, чтобы эта информация передавалась обратно в VC1, пусть данные называются «информация»

Код, который я надеялся использовать, был таким. Я получаю доступ к стеку VC и присваиваю переменные необязательной переменной «info» (которая дается во время компиляции, стек не знает, какой тип VC находится в стеке.

let nav = self.navigationController
let nextView = nav?.viewControllers[(nav?.viewControllers.count)! - 1]
****//code that isn't working
nextView.info = self.info => Value of type 'UIViewController?' has no member 'info'

****//This works fine
nav?.popViewController(animated: true)

Ответы [ 3 ]

0 голосов
/ 27 июня 2018

Хрупко полагать, что вы находитесь в стеке навигации и что контроллер представления, находящийся под вами, является тем, с кем вам нужно поговорить.

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

Было бы лучше / чище установить протокол делегата между двумя контроллерами представления и сделать себя делегатом нового контроллера представления, прежде чем нажимать его. Затем он просто отправит сообщение своему делегату, чтобы передать данные обратно.

0 голосов
/ 27 июня 2018

nextView считается суперклассом UIViewController, поскольку массив viewControllers из UINavigationController определен так ([UIViewController]).

Если ваш VC1 имеет тип FirstVC (подкласс UIViewController), вы должны привести его к фактическому классу, чтобы иметь возможность "видеть" ваши дополнительные свойства. То же самое с вашими следующими контроллерами представления. Итак, что произойдет, если вы сделаете это?

let nextView = nav?.viewControllers[(nav?.viewControllers.count)! - 1] as? SecondVC

Конечно, предполагая, что ваш nextView имеет класс SecondVC. Помните, что объектно-ориентированное программирование имеет полиморфизм , в котором все ваши контроллеры представления являются потомками UIViewController и, таким образом, они являются a UIViewController в целом, и такие ситуации могут возникнуть.

В любом случае, правильным способом было бы определить протокол, заставить FirstVC соответствовать ему, передать первый контроллер вида в качестве параметра в SecondVC и, во втором контроллере представления, вызвать метод протокола обратно к первый вид контроллера при выборе опции. Что-то вроде:

protocol PassDataBackProtocol {
    var result: String
}

class FirstVC: UIViewController, PassDataBackProtocol {
    var result: String = "" {
        didSet {
            // Update your view
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let secondVC = segue.destination as? SecondVC {
            secondVC.firstVC = self
        }
    }
}

class SecondVC: UIViewController {
    weak var firstVC: PassDataBackProtocol?

    func didChangeValue(newValue: String) {
        firstVC?.result = newValue
        navigationController?.popViewController(animated: true)
    }
}

Если вы используете pushViewController(_:animated:) вместо segues, тогда установите firstVC перед выполнением push.

EDIT: Я добавил свойство weak к обратному указателю, поскольку важно избегать сохранения циклов.

0 голосов
/ 27 июня 2018

Вам нужно разыграть его

if let let nextView = nav?.viewControllers[(nav?.viewControllers.count)! - 1] as? VCName {
   nextView.info = self.info
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...