【问题标题】:Pass data between unrelated ViewControllers在不相关的 ViewController 之间传递数据
【发布时间】:2018-11-16 02:29:01
【问题描述】:

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

注意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 中,我使用应该填充 ThirdViewController 的数据(姓名、姓氏、性别、出生等)解析结构 (LoginResponse) 中的 JSON。我已经在 LoginViewController 中使用了这个 sn-p:

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 已经做到了,如果我选择使用 Delegate 方法或 NotificationCenter 方法传递数据,这是必要的。

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

【问题讨论】:

    标签: ios swift delegates nsnotificationcenter


    【解决方案1】:

    你可以试试这样的:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-24
        • 2017-01-22
        • 2019-12-05
        • 1970-01-01
        • 2017-12-09
        • 2016-03-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多