在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.我知道如何使用委托传递数据,只是对闭包感到好奇吗?
我们怎样才能做到这一点?
如果您需要在多个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")
}
这只是我快速为您编写的示例代码,您可以根据需要修改对象。希望能解决您的问题。
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")
}
}