Как передавать данные с контроллера модального просмотра обратно при увольнении
Я выполнил инструкции здесь, но я до сих пор не уверен в этой части:
modalVC.delegate=self;
self.presentViewController(modalVC, animated: true, completion: nil)
Я попытался создать экземпляр контроллера представления программно, но все же безрезультатно.
здесь мой код для отклонения модального контроллера:
@IBAction func dismissViewController(_ sender: UIBarButtonItem) {
self.dismiss(animated: true) {
//
}
}
Я использую раскадровку, чтобы перейти с модальным видом.
Это данные, которые я хочу передать обратно в родительский контроллер представления:
var typeState = "top"
var categoryState = "casual"
Какие два значения String.
Изменить:
Я попытался передать данные с контроллера модального представления, как показано:
@IBAction func dismissViewController(_ sender: UIBarButtonItem) {
self.dismiss(animated: true, completion: nil)
delegate?.sendValue(value: "success")
if let presenter = presentingViewController as? OOTDListViewController {
presenter.receivedValue = "test"
}
}
тогда как на контроллере родительского представления я сделал следующее:
func sendValue(value: NSString) {
receivedValue = value as String
}
@IBAction func printReceivedValue(_ sender: UIButton) {
print(receivedValue)
}
Я все равно не получаю никакого значения, когда нажимаю кнопку печати.
Модальный контроллер:
protocol ModalViewControllerDelegate
{
func sendData(typeState: String, categoryState: String)
}
var delegate:ModalViewControllerDelegate!
var typeState = "top"
var categoryState = "casual"
@IBAction func dismissViewController(_ sender: UIBarButtonItem) {
self.dismiss(animated: true, completion: nil)
delegate?.sendData(typeState: typeState as String, categoryState: categoryState as String)
}
Контроллер родительского контроля:
class parentViewController: UICollectionViewController, ModalViewControllerDelegate {
var typeState: String?
var categoryState: String?
func sendData(typeState: String, categoryState: String) {
self.typeState = typeState as String
self.categoryState = categoryState as String
}
@IBAction func printReceivedValue(_ sender: UIButton) {
print(typeState)
}
Изменить:
Здесь мой новый код без использования метода делегата:
Модальный контроллер:
@IBAction func dismissViewController(_ sender: UIBarButtonItem) {
self.dismiss(animated: true, completion: nil)
if let presenter = presentingViewController as? OOTDListViewController {
presenter.typeState = typeState
presenter.categoryState = categoryState
}
}
OOTDListViewController:
@IBAction func presentModalView(_ sender: UIBarButtonItem) {
let modalView = storyboard?.instantiateViewController(withIdentifier: "filterViewController") as! ModalViewController
let navModalView: UINavigationController = UINavigationController(rootViewController: modalView)
self.present(navModalView, animated: true, completion: nil)
}
@IBAction func printValue(_ sender: UIButton) {
print(typeState)
print(categoryState)
}
Ответы
Ответ 1
В зависимости от данных, которые вы хотите передать, вы можете создать свойство в представлении контроллера представления, которое вы можете установить при отклонении модального контроллера представления, чтобы вы могли освободить себя от делегата.
Например, у вас есть ContactsViewController
, удерживая свойство var contacts: [Contact] = []
. Когда вы хотите создать новый контакт, вы представляете контроллер модального представления с разными значениями, необходимыми для создания нового объекта Contact
. Когда вы закончите и хотите отклонить контроллер вида, вы вызываете функцию так же, как и в вашем коде, но устанавливаете свойство в ContactsViewController
. Он будет выглядеть примерно так:
@IBAction func dismissViewController(_ sender: UIBarButtonItem) {
if let presenter = presentingViewController as? ContactsViewController {
presenter.contacts.append(newContact)
}
dismiss(animated: true, completion: nil)
}
EDIT:
Если вы не хотите использовать делегат, вот как вы это сделаете:
В OOTDListViewController
:
var testValue: String = ""
@IBAction func printReceivedValue(_ sender: UIButton) {
print(testValue)
}
В вашем модульном контроллере просмотра (я назову его PresentedViewController
):
@IBAction func dismissViewController(_ sender: UIBarButtonItem) {
// if your OOTDListViewController is part of a UINavigationController stack, this check will probably fail.
// you need to put a breakpoint here and check if the presentingViewController is actually a UINavigationController.
// in that case, you will need to access the viewControllers variable and find your OOTDListViewController
if let presenter = presentingViewController as? OOTDListViewController {
presenter.testValue = "Test"
}
dismiss(animated: true, completion: nil)
}
Если вы хотите использовать делегат, вот как это сделать:
В вашем OOTDListViewController:
protocol ModalDelegate {
func changeValue(value: String)
}
class OOTDListViewController: ModalDelegate {
var testValue: String = ""
@IBAction func presentViewController() {
// here, you either create a new instance of the ViewController by initializing it, or you instantiate it using a storyboard.
// for simplicity, I'll use the first way
// in any case, you cannot use a storyboard segue directly, bevause you need access to the reference of the presentedViewController object
let presentedVC = PresentedViewController()
presentedVC.delegate = self
present(presentedVC, animated: true, completion: nil)
}
func changeValue(value: String) {
testValue = value
print(testValue)
}
}
В вашем PresentedViewController
:
class PresentedViewController {
var delegate: ModalDelegate?
var testValue: String = ""
@IBAction func dismissViewController(_ sender: UIBarButtonItem) {
if let delegate = self.delegate {
delegate.changeValue(testValue)
}
dismiss(animated: true, completion: nil)
}
}
Ответ 2
Вам нужно вызвать метод делегата в методе dismissViewController
@IBAction func dismissViewController(_ sender: UIBarButtonItem) {
delegate?.sendData(typeState: "top", categoryState: "casual")
self.dismiss(animated: true) {
//
}
}
в вашем классе Modal ViewController создайте делегат
var delegate: MyProtocol?
создать протокол с именем метода sendData в MyProtocol и в вашем представленииViewController, где вы назначаете делегат, реализовать метод MyProtocol
protocol MyProtocol: class {
func sendData(typeState: String, categoryState: String)
}
class ViewController: UIViewController, MyProtocol {
var typeState: String?
var categoryState: String?
func sendData(typeState: String, categoryState: String) {
self.typeState = typeState
self.categoryState = categoryState
}
}
Ответ 3
Я использую табуляцию, поэтому рабочий код ниже
if let tabBar = self.presentingViewController as? UITabBarController {
let homeNavigationViewController = tabBar.viewControllers![0] as? UINavigationController
let homeViewController = homeNavigationViewController?.topViewController as! HomeController
homeViewController._transferedLocationID = self.editingLocationID!
}
Ответ 4
Если вы используете навигационный контроллер, вам сначала нужно взять UINavigation Controller, а затем получить правильный ViewController из стека Navigation Controller.
Вот как мой код выглядел в таком случае.
@IBAction func dismissViewController(_ sender: UIBarButtonItem) {
if let navController = presentingViewController as? UINavigationController {
let presenter = navController.topViewController as! OOTDListViewController
presenter.testValue = "Test"
}
dismiss(animated: true, completion: nil)
}