Swift 3: вернуться к последнему ViewController с отправкой данных
Я пытаюсь вернуться в свой las viewController с отправкой данных, но это не работает.
Когда я просто использую popViewController, я могу вернуться на страницу, но я не могу переместить свои данные из B в A.
Вот мой код:
func goToLastViewController() {
let vc = self.navigationController?.viewControllers[4] as! OnaylarimTableViewController
vc.onayCode.userId = taskInfo.userId
vc.onayCode.systemCode = taskInfo.systemCode
self.navigationController?.popToViewController(vc, animated: true)
}
4 ответа
Чтобы передать данные от дочернего к родительскому контроллеру, вы должны передать данные с помощью шаблона делегата.
Шаги по реализации шаблона делегирования. Предположим, что A - это родительский viewController, а B - это дочерний viewController.
Создайте протокол и создайте переменную делегата в B
Расширить протокол в A
передать ссылку на B из A, когда Push или Present viewcontroller
Определите метод делегата в A, получите действие.
После этого в соответствии с вашим условием вы можете вызвать метод делегата из B.
Вы можете использовать шаблон координатора
Например, у меня есть 2 экрана. Первый отображает информацию о пользователе, и оттуда он переходит на экран выбора своего города. Информация об измененном городе должна отображаться на первом экране.
final class CitiesViewController: UITableViewController {
// MARK: - Output -
var onCitySelected: ((City) -> Void)?
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
onCitySelected?(cities[indexPath.row])
}
...
}
UserEditViewController:
final class UserEditViewController: UIViewController, UpdateableWithUser {
// MARK: - Input -
var user: User? { didSet { updateView() } }
@IBOutlet private weak var userLabel: UILabel?
private func updateView() {
userLabel?.text = "User: \(user?.name ?? ""), \n"
+ "City: \(user?.city?.name ?? "")"
}
}
И координатор:
protocol UpdateableWithUser: class {
var user: User? { get set }
}
final class UserEditCoordinator {
// MARK: - Properties
private var user: User { didSet { updateInterfaces() } }
private weak var navigationController: UINavigationController?
// MARK: - Init
init(user: User, navigationController: UINavigationController) {
self.user = user
self.navigationController = navigationController
}
func start() {
showUserEditScreen()
}
// MARK: - Private implementation
private func showUserEditScreen() {
let controller = UIStoryboard.makeUserEditController()
controller.user = user
controller.onSelectCity = { [weak self] in
self?.showCitiesScreen()
}
navigationController?.pushViewController(controller, animated: false)
}
private func showCitiesScreen() {
let controller = UIStoryboard.makeCitiesController()
controller.onCitySelected = { [weak self] city in
self?.user.city = city
_ = self?.navigationController?.popViewController(animated: true)
}
navigationController?.pushViewController(controller, animated: true)
}
private func updateInterfaces() {
navigationController?.viewControllers.forEach {
($0 as? UpdateableWithUser)?.user = user
}
}
}
Тогда нам просто нужно запустить координатор:
coordinator = UserEditCoordinator(user: user, navigationController: navigationController)
coordinator.start()
Вы должны отправить обратно в последний ViewController с 2 вариантами.
1. Расслабьтесь. (С использованием раскадровки)
Вы можете сослаться на эту ссылку.
2. Использование делегата / протокола.
Вы можете сослаться на эту ссылку.
Также эта ссылка будет полезна для вас.
Вы должны сделать это с помощью delegate protocol
class MyClass: NSUserNotificationCenterDelegate
Реализация будет выглядеть следующим образом:
func userDidSomeAction() {
//implementation
}
И, конечно же, вы должны реализовать deletegete в родительском классе, как
childView.delegate = self
Проверьте это для получения дополнительной информации https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html