如何在使用Swift消除ViewController的过程中将值从ViewController B传递给ViewController A?

时间:2019-04-26 04:41:01

标签: ios swift delegates

我的场景是,我在关闭视图控制器期间尝试将值从ViewController B传递到ViewController A。在这里,我使用了下面的代码,但无法在ViewController A中获取值。

ViewController B

// protocol used for sending data back
protocol isAbleToReceiveData {
    func pass(data: String)  //data: string is an example parameter
}

// Making this a weak variable so that it won't create a strong reference cycle
var delegate: isAbleToReceiveData?

override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(true)
        self.delegate?.pass(data: "someData") //call the func in the previous vc
}

@IBAction func Click_action(_ sender: Any) {
        self.dismiss(animated: false, completion: nil)
        self.delegate?.pass(data: "someData") 
 }

ViewController A

class MyViewController: UIViewController, isAbleToReceiveData {

func pass(data: String) {
        print("USER: \(data)")
    }
}

// MARK: FromTouch Action
    @objc func fromTouchTapped(_ sender: UITapGestureRecognizer) {

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let viewController = storyboard.instantiateViewController(withIdentifier: "ViewControllerB")
        viewController.modalTransitionStyle = .crossDissolve
        let navController = UINavigationController(rootViewController: viewController)
        present(navController, animated: true, completion: nil)
    }

3 个答案:

答案 0 :(得分:0)

第一个B应该有一个指向A的委托变量。这意味着它们必须是直接连接,例如A是B的父级。

如果A和B之间没有直接连接,另一个简便的解决方案是使用Notification Center。其中B生成一个事件,而A添加该事件的观察者。您可以按照以下示例操作:Using Notification Center In Swift

答案 1 :(得分:0)

您的ViewController A看起来不错,但似乎您没有设置ViewController B的delegate变量,请在启动ViewController B后立即执行此操作,如下所示:

viewControllerA.present(viewControllerB, animated: true)
viewControllerB.delegate = viewControllerA // notice this line

由于您位于viewControllerA的实例中,因此将viewControllerA替换为self

下面的完整委派示例

protocol IsAbleToReceiveData: class {
    func pass(data: String)  //data: string is an example parameter
}

class ViewControllerA: UIViewController, IsAbleToReceiveData {

    override func viewDidLoad() {
        super.viewDidLoad()

        let button = UIButton(frame: CGRect(x: 15, y: 100, width: 0, height: 0))
        button.addTarget(self, action: #selector(launchAction), for: .touchUpInside)
        button.setTitle("Launch ViewController B", for: .normal)
        button.setTitleColor(.black, for: .normal)
        button.sizeToFit()
        self.view.addSubview(button)
    }

    @objc func launchAction() {
        let viewController = ViewControllerB() // guard let viewController = self.storyboard?.instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB else { return }
        viewController.delegate = self
        self.present(viewController, animated: true)
    }

    func pass(data: String) {
        print("Received Data: \(data)")
    }

}

class ViewControllerB: UIViewController {

    weak var delegate: IsAbleToReceiveData?

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = .white

        let button = UIButton(frame: CGRect(x: 15, y: 100, width: 0, height: 0))
        button.addTarget(self, action: #selector(exitAction), for: .touchUpInside)
        button.setTitle("Exit ViewController B", for: .normal)
        button.setTitleColor(.black, for: .normal)
        button.sizeToFit()
        self.view.addSubview(button)
    }

    @objc func exitAction() {
        self.delegate?.pass(data: "Hello World!")
        self.dismiss(animated: true)
    }

    func pass(data: String) {
        print("Received Data: \(data)")
    }

}

答案 2 :(得分:0)

一切都对,您错过了ViewControllerA时在ViewControllerB中分配代理人。

if let VC_B = self.storyboard?.instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB{
    VC_B.delegate = self
    VC_B.modalTransitionStyle = .crossDissolve
    self.present(VC_B, animated: true, completion: nil)
}

注意

  

让viewController =   self.storyboard?.instantiateViewController(withIdentifier:   “ ViewControllerB”)为? ViewControllerB

     

     

让viewController =   self.storyboard?.instantiateViewController(withIdentifier:   “ ViewControllerB”)