#ios #swift #uiviewcontroller #uinavigationcontroller #uikit
#iOS #swift #uiviewcontroller #uinavigationcontroller #uikit
Вопрос:
У меня есть пара UIViewControllers
подобных показанных
Я хочу передать данные из B в C, а также выполнить этот переход. До сих пор я предлагал 2 возможных решения:
- Создайте новый экземпляр класса C
UIViewController
(и сохраните ссылку на данные в нем), извлеките B изnavigation controller
и вставьте C в него. - Отправьте данные в A, извлеките B из
navigation controller
, а затем вviewWillAppear
методе A проверьте, не равны ли данные нулю, чтобы узнать, следует ли отправлять их в C и выполнятьsegue
.
Должен ли я использовать любой из этих 2 подходов? Или есть более элегантное / правильное решение для этой ситуации?
Спасибо
Комментарии:
1. Это собственный контроллер просмотра
2. Я не понимаю. A подталкивает к B? И с B вы хотите перейти на C?
3. Сценарий заключается в том, что я перешел от A к B, и теперь я хочу перейти от B к C, но также передать некоторые данные
4. Вы уже приняли ответ, но в дальнейшем постарайтесь быть более точным с вашим языком. Переход от A к B, а затем переход от B к C ничего не значит. Вы нажимаете или представляете? Является ли A родительским для B и C, и вы переходите между дочерними элементами? Является ли A собственным контроллером просмотра, и пользователь может нажать на B или C? Сейчас это не имеет значения, но изучите терминологию, это очень поможет.
Ответ №1:
Организуйте диспетчер данных родительского контроллера или используйте Core Data.
В случае хранения данных в родительском контроллере используйте внедрение зависимостей, как описано здесь
Вот пример для вашего случая:
var dataFromC = "" // or nil
var dataFromB = "" // or nil
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "B",
let viewController = segue.destinationViewController as? BViewController {
viewController.dataFromC = self.dataFromC
// declare method in BViewController
// var method : ((String) -> ())? = nil
viewController.method = {[weak self] valueFromB in
self?.dataFromB = valueFromB
}
}
if segue.identifier == "C",
let viewController = segue.destinationViewController as? CViewController {
viewController.dataFromB = self.dataFromB
// declare method in CViewController
// var method : ((String) -> ())? = nil
viewController.method = {[weak self] valueFromC in
self?.dataFromC = valueFromC
}
}
}
Если вы хотите передать значение родительскому контроллеру из BViewController
, используйте self.method("yourValueFromB")
, где вы измените значение. Для случая с CViewController
используйте тот же подход.
Комментарии:
1. Итак, это было бы похоже на второй подход, который я опубликовал?
2. ДА. Существует так много способов сделать это. В приведенном выше примере используется внедрение зависимостей, и здесь передается функция (
closure
) от родительского контроллераmethod
. Также вы можете перенести это в протоколы или объекты обработчика. Все комбинации работают.
Ответ №2:
Как правило, B должен отправлять данные обратно на исходный контроллер представления A с помощью шаблона протокола делегирования. Затем A должен иметь возможность решить в реализации метода делегирования, какие данные получены от B и куда отправлять эти данные, которые в данном случае являются C.
Таким образом, ваш код выглядит более организованным.