我们如何将闭包传递给app流中的任何ViewController?

问题描述 投票:0回答:2

在View Controller A中,

var completionBlock: (((String) -> ()))? = nil

我正在调用完成块(ViewController A):

if let block = completionBlock {
     block("block data to pass") 
}

我不想将完成数据传递给ViewController B,而是想传递给从ViewController B呈现的ViewController C.

简单来说,我想将闭包数据从ViewController A传递给ViewController C.我知道如何使用委托传递数据,只是对闭包感到好奇吗?

我们怎样才能做到这一点?

ios closures swift4.2 pass-data
2个回答
1
投票

如果您需要在多个viewControllers之间传递此块,则几乎没有选项:

1-传递闭包作为变量:在VC-A,VC-C中间的每个新ViewController上创建一个变量,并在它们之间传递它们

例如:

//View Controller B:
var block:(((String) -> ()))? = nil

//Pass from A-B
if let viewcontrollerB = XXXX { //instantiate ViewController B from A
    viewcontrollerB.block = self.block
}


//ViewController C:
var block:(((String) -> ()))? = nil

//Pass from B-C
if let viewcontrollerC = XXXX { //instantiate ViewController C from B
    viewcontrollerC.block = self.block
}

//Call the block from ViewController C
if let block = self.block {
   block("block data to pass") 
}

2通过通知中心您可以将此块从任意视图控制器传递给任何其他:

//send notification:
let notification = Notification(name: Notification.Name("pass block"), object: block, userInfo: nil)
NotificationCenter.default.post(notification)

3 - 从共享对象访问使用单例设计并创建静态共享对象,并从不同的视图控制器读取/写入对象

//AppDelegate:
static var block:(((String) -> ()))? = nil

//ViewController A:
AppDelegate.block = XXX

//ViewController C:
if let block = AppDelegate.block {
   block("block data to pass") 
}

1
投票

这只是我快速为您编写的示例代码,您可以根据需要修改对象。希望能解决您的问题。

import UIKit

class ViewControllerA: UIViewController {
    var block:(((String) -> ()))? = { input in
        print(input)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "A"
        let VCB = ViewControllerB()
        let VCC = ViewControllerC()
        VCC.block = block
        VCB.VCC = VCC
        self.navigationController?.pushViewController(VCB, animated: true)

    }


}

class ViewControllerB: UIViewController {
    var VCC:ViewControllerC?
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .gray

    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        if let VCC = VCC {
            self.present(VCC, animated: true, completion: nil)
        }
    }


}

class ViewControllerC: UIViewController {
    var block:(((String) -> ()))? = nil

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .yellow
        //Will run the block that has been passed
        block?("test")
    }


}
© www.soinside.com 2019 - 2024. All rights reserved.