ios 关闭时如何将数据从模态视图控制器传回

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40126662/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 10:36:50  来源:igfitidea点击:

How to pass data from modal view controller back when dismissed

iosswift

提问by lws803

I've followed the instructions herebut I'm still unsure about this part:

我已按照此处的说明进行操作但我仍然不确定这部分:

modalVC.delegate=self;
        self.presentViewController(modalVC, animated: true, completion: nil) 

I've tried instantiating the view controller programmatically but still to no avail.

我试过以编程方式实例化视图控制器,但仍然无济于事。

here's my code for when dismissing the modal view controller:

这是我关闭模态视图控制器时的代码:

@IBAction func dismissViewController(_ sender: UIBarButtonItem) {
        self.dismiss(animated: true) { 
            //
        }
    }

I'm using storyboard to segue with modal view.

我正在使用情节提要与模态视图进行拼接。

This is the data I wish to transfer back to the parent view controller:

这是我希望传输回父视图控制器的数据:

var typeState = "top"
 var categoryState = "casual"

Which are two String values.

这是两个字符串值。

Edit:

编辑:

I've tried to pass data from the modal view controller as shown:

我尝试从模态视图控制器传递数据,如下所示:

@IBAction func dismissViewController(_ sender: UIBarButtonItem) {
        self.dismiss(animated: true, completion: nil)
        delegate?.sendValue(value: "success")
        if let presenter = presentingViewController as? OOTDListViewController {
            presenter.receivedValue = "test"
        }
    }

whereas on the parent view controller I did as such:

而在父视图控制器上,我是这样做的:

func sendValue(value: NSString) {
        receivedValue = value as String
    }
  @IBAction func printReceivedValue(_ sender: UIButton) {
        print(receivedValue)
    }

I still couldnt receive any value when I hit the print button.

当我点击打印按钮时,我仍然无法收到任何值。

Modal view controller:

模态视图控制器:

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)

    }

Parent view controller:

父视图控制器:

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)
 }

Edit:

编辑:

Here's my new code without using delegate method:

这是我不使用委托方法的新代码:

Modal view Controller:

模态视图控制器:

@IBAction func dismissViewController(_ sender: UIBarButtonItem) {
        self.dismiss(animated: true, completion: nil)
        if let presenter = presentingViewController as? OOTDListViewController {
            presenter.typeState = typeState
            presenter.categoryState = categoryState
        }
    }

OOTDListViewController:

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)
    }

回答by smeshko

Depending on the data you want to pass, you can create a property in the presenting view controller, which you can set when dismissing the modal view controller, so you can spare yourself the delegate.

根据您要传递的数据,您可以在呈现视图控制器中创建一个属性,您可以在关闭模态视图控制器时设置该属性,这样您就可以省去委托。

For example, you have a ContactsViewController, holding a var contacts: [Contact] = []property. When you want to create a new contact, you present a modal view controller with the different values you need to create a new Contactobject. When you are done and want to dismiss the view controller, you call the function as you did in your code, but set the property in the ContactsViewController. It will look something like this:

例如,您有一个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:

编辑:

If you don'twant to use a delegate, this is how you go about it:

如果你希望使用一个委托,这是你如何去做:

In your OOTDListViewController:

在您的OOTDListViewController

var testValue: String = ""

@IBAction func printReceivedValue(_ sender: UIButton) {
    print(testValue)
}

In your modal view controller (I'll call it PresentedViewController) :

在您的模态视图控制器中(我称之为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)
}

If you wantto use a delegate, this is how to do it:

如果你使用委托,这是如何做到的:

In your OOTDListViewController:

在您的 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)
}

}

}

In your PresentedViewController:

在您的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)
    }

}

回答by coders

i am using the tabbar so the working code as below

我正在使用标签栏,因此工作代码如下

            if let tabBar = self.presentingViewController as? UITabBarController {
            let homeNavigationViewController = tabBar.viewControllers![0] as? UINavigationController
            let homeViewController = homeNavigationViewController?.topViewController as! HomeController
            homeViewController._transferedLocationID = self.editingLocationID!
        }

回答by Eric Duffett

If using a navigation controller you will have to first grab the UINavigation Controller and then get the correct ViewController from the Navigation Controller stack.

如果使用导航控制器,您必须首先获取 UINavigation 控制器,然后从导航控制器堆栈中获取正确的 ViewController。

Here's how my code looked in that case.

这是我的代码在这种情况下的样子。

@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)
}

回答by Suhit Patil

You need to call the delegate method in dismissViewControllermethod

您需要在dismissViewController方法中调用委托方法

@IBAction func dismissViewController(_ sender: UIBarButtonItem) {
        delegate?.sendData(typeState: "top", categoryState: "casual")
        self.dismiss(animated: true) { 
            //
        }
 }

in you Modal ViewController class create delegate

在你的 Modal ViewController 类中创建委托

var delegate: MyProtocol?

create a protocol with the method name sendData in MyProtocol and in your presentingViewController where you are assigning the delegate, implement the MyProtocol method

在 MyProtocol 和您正在分配委托的 PresentingViewController 中创建一个方法名称为 sendData 的协议,实现 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
    }
 }