Ios 在不相关的视图控制器之间传递数据

Ios 在不相关的视图控制器之间传递数据,ios,swift,delegates,nsnotificationcenter,Ios,Swift,Delegates,Nsnotificationcenter,我试图实现一个登录屏幕,将数据放入视图控制器,通过覆盖tabBarController didSelect方法调用登录视图控制器,如下所示: import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, UITabBarControllerDelegate { // This delegate open the modal view after open the desired v

我试图实现一个登录屏幕,将数据放入视图控制器,通过覆盖tabBarController didSelect方法调用登录视图控制器,如下所示:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UITabBarControllerDelegate {

// This delegate open the modal view after open the desired view.
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        if viewController is MyThirdViewController {
            if let loginPopupVC = tabBarController.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") {
                tabBarController.present(loginPopupVC, animated: true)
            }
        }
    }
}
请注意,TabBarController和ThirdViewController之间没有任何segue,因为我覆盖了TabBarController,如下所示:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UITabBarControllerDelegate {

// This delegate open the modal view after open the desired view.
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        if viewController is MyThirdViewController {
            if let loginPopupVC = tabBarController.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") {
                tabBarController.present(loginPopupVC, animated: true)
            }
        }
    }
}
现在,在我的LoginViewController中,我解析了一个结构LoginResponse中的JSON,其中包含应该填充第三个LoginViewController名称、姓氏、性别、出生等的数据。我已经在LoginViewController中使用了以下代码段:

struct LoginResponse : Decodable {
    var name: String
    var surname: String
    var sex: String
    var birth: String
}

class LoginViewController: UIViewController, UITextFieldDelegate, XMLParserDelegate {

@IBAction func cancelLogin(_ sender: UIButton) {
        //LoginViewController will close and ThirdViewController will open
        dismiss(animated: true, completion: nil)
    }

@IBAction func makeLogin(_ sender: UIButton) {
        //LoginViewController brings data, closing itself and opening ThirdViewController
        self.updateUI()
        self.dismiss(animated: true, completion: nil)
    }

func updateUI() {
        do {
            let jsonDecoder = JSONDecoder()
            let myjson = "{\"name\": \"MyName\", \"surname\": \"MySurname\", \"sex\": \"Male\", \"birth\": \"1980-05-15\"}"
            let loginResult = try jsonDecoder.decode(LoginResponse.self, from: Data(myjson.utf8))
        }
        catch let jsonErr{
            print(jsonErr)
        }

    }
}
现在,我想将loginResult中的数据传递给ThirdViewController

我想我无法从LoginViewController调用ThirdViewController,因为TabBarController已经调用了它,如果我选择使用委托方法或NotificationCenter方法传递数据,这是必要的


我想知道在这种情况下,ViewController之间传递数据选项中的哪一个会更好地工作,因为通常会在示例中解释这些方法,其中两个视图控制器通过一个segue连接,但在我的情况下,屏幕的流动是不寻常的。谢谢。

好的。我建议在loginPopupVC中声明一个变量,以包含对ThirdViewController的引用,因此在tabBar:didSelect中,在实例化loginVC之后,将引用传递给ThirdVC,但在显示登录之前。在Login中,所述变量是类级别的,因此您可以从updateUI func访问它。现在,在ThirdView中声明一个包含json的方法或变量并传递它。

您可以尝试以下方法:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UITabBarControllerDelegate {

    // This delegate open the modal view after open the desired view.
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        if viewController is MyThirdViewController {
            if let loginPopupVC = tabBarController.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") {
                loginPopupVC.delegate = tabBarController
                tabBarController.present(loginPopupVC, animated: true)
            }
        }
    }
}
对于loginPopupVC:

struct LoginResponse : Decodable {
    var name: String
    var surname: String
    var sex: String
    var birth: String
}

class LoginViewController: UIViewController, UITextFieldDelegate, XMLParserDelegate {

    var delegate: loginDelegate?

    @IBAction func cancelLogin(_ sender: UIButton) {
        //LoginViewController will close and ThirdViewController will open
        dismiss(animated: true, completion: nil)
    }

    @IBAction func makeLogin(_ sender: UIButton) {
        //LoginViewController brings data, closing itself and opening ThirdViewController
        self.updateUI()
        self.dismiss(animated: true, completion: nil)
    }

    func updateUI() {
        do {
            let jsonDecoder = JSONDecoder()
            let myjson = "{\"name\": \"MyName\", \"surname\": \"MySurname\", \"sex\": \"Male\", \"birth\": \"1980-05-15\"}"
            let loginResult = try jsonDecoder.decode(LoginResponse.self, from: Data(myjson.utf8))
            // Pass data using delegate
            delegate?.handleLogin(with: loginResult)

        }
        catch let jsonErr{
            print(jsonErr)
        }

    }
}
然后对于tabBarController类:

protocol loginDelegate: class {
    func handleLogin(with object: LoginResponse)
}

class myTabBarController: UITabBarController, loginDelegate {

    // regular tabBarController lifecycle methods

    func handleLogin(with object: LoginResponse) {
        // do work with data
    }

}