Swift 与最近有关用于在VCs之间传递数据的闭包的问题保持一致,在rootVC中使用containerVC时,我将如何做同样的事情?

Swift 与最近有关用于在VCs之间传递数据的闭包的问题保持一致,在rootVC中使用containerVC时,我将如何做同样的事情?,swift,Swift,我最近看到了一个关于使用闭包在VCs之间传递数据的问题(如果您愿意,可以找到链接),其中一个VC嵌入到导航控制器中。虽然在那里使用闭包相当容易,因为两个风投之间有一个直接的接触点(以segue的形式),但我一直在想,如果不是这样的话,这将如何工作 作为一个例子,考虑下面的设置(类似于激发这篇文章的OG问题): RootVC,它有一个计数器UILabel 占据RootVC下半部分的子容器VC,它有一个按钮,按下该按钮将使RootVC上的UILabel增加一个。 我准备了以下代码(部分代码取自OG问

我最近看到了一个关于使用闭包在VCs之间传递数据的问题(如果您愿意,可以找到链接),其中一个VC嵌入到导航控制器中。虽然在那里使用闭包相当容易,因为两个风投之间有一个直接的接触点(以segue的形式),但我一直在想,如果不是这样的话,这将如何工作

作为一个例子,考虑下面的设置(类似于激发这篇文章的OG问题):

RootVC,它有一个计数器UILabel

占据RootVC下半部分的子容器VC,它有一个按钮,按下该按钮将使RootVC上的UILabel增加一个。

我准备了以下代码(部分代码取自OG问题):

RootVC:

class RootVC: UIViewController {

    var tappedCount: Int = 0

    let pagingContainer: UIView = {
        let view = UIView()
        view.backgroundColor = .white
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    lazy var label: UILabel = {
        let label = UILabel()
        label.text = "\(tappedCount)"
        label.textAlignment = .center
        label.font = UIFont(name: "Copperplate", size: 90)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        view.addSubview(label)
        view.addSubview(pagingContainer)

        pagingContainer.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        pagingContainer.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1).isActive = true
        pagingContainer.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
        pagingContainer.heightAnchor.constraint(equalToConstant: 500).isActive = true

        let pageController = PageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
               addChild(pageController)
               pageController.didMove(toParent: self)
               pageController.view.translatesAutoresizingMaskIntoConstraints = false
               pagingContainer.addSubview(pageController.view)

               pageController.view.heightAnchor.constraint(equalTo: pagingContainer.heightAnchor, multiplier: 1).isActive = true
               pageController.view.widthAnchor.constraint(equalTo: pagingContainer.widthAnchor, multiplier: 1).isActive = true

               pageController.view.topAnchor.constraint(equalTo: pagingContainer.topAnchor).isActive = true
               pageController.view.bottomAnchor.constraint(equalTo: pagingContainer.bottomAnchor).isActive = true
               pageController.view.leadingAnchor.constraint(equalTo: pagingContainer.leadingAnchor).isActive = true
               pageController.view.trailingAnchor.constraint(equalTo: pagingContainer.trailingAnchor).isActive = true


        label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true


 label.bottomAnchor.constraint(equalTo: pagingContainer.topAnchor).isActive = true     
          }
       }
class SubContainerVC: UIViewController {

    var callback : (() -> Void)?

    let button: UIButton = {
        let button = UIButton()
        button.setTitle("Button!", for: .normal)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
        button.backgroundColor = .green
        return button
    }()

    @objc func buttonPressed(_ sender: UIButton) {
        print("Hello")
        //Pressing this button should increment the label on RootVC by one.
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemBlue
        view.addSubview(button)

        button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }

}
class PageViewController: UIPageViewController {

    lazy var subViewControllers:[UIViewController] = {
        return [SubContainerVC()]
    }()


    init(transitionStyle style:
        UIPageViewController.TransitionStyle, navigationOrientation: UIPageViewController.NavigationOrientation, options: [String : Any]? = nil) {
        super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
    }



    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()


        dataSource = self
        delegate = self
        setViewControllerFromIndex(index: 0)
    }

    func setViewControllerFromIndex(index:Int) {
        self.setViewControllers([subViewControllers[index]], direction: UIPageViewController.NavigationDirection.forward, animated: true, completion: nil)
    }
}

extension PageViewController: UIPageViewControllerDelegate, UIPageViewControllerDataSource {
    func presentationCount(for pageViewController: UIPageViewController) -> Int {
        return subViewControllers.count
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        let currentIndex:Int = subViewControllers.firstIndex(of: viewController) ?? 0
        if currentIndex <= 0 {
            return nil
        }
        return subViewControllers[currentIndex-1]
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        let currentIndex:Int = subViewControllers.firstIndex(of: viewController) ?? 0
        if currentIndex >= subViewControllers.count-1 {
            return nil
        }
        return subViewControllers[currentIndex+1]
    }
}
分包服务:

class RootVC: UIViewController {

    var tappedCount: Int = 0

    let pagingContainer: UIView = {
        let view = UIView()
        view.backgroundColor = .white
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    lazy var label: UILabel = {
        let label = UILabel()
        label.text = "\(tappedCount)"
        label.textAlignment = .center
        label.font = UIFont(name: "Copperplate", size: 90)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        view.addSubview(label)
        view.addSubview(pagingContainer)

        pagingContainer.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        pagingContainer.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1).isActive = true
        pagingContainer.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
        pagingContainer.heightAnchor.constraint(equalToConstant: 500).isActive = true

        let pageController = PageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
               addChild(pageController)
               pageController.didMove(toParent: self)
               pageController.view.translatesAutoresizingMaskIntoConstraints = false
               pagingContainer.addSubview(pageController.view)

               pageController.view.heightAnchor.constraint(equalTo: pagingContainer.heightAnchor, multiplier: 1).isActive = true
               pageController.view.widthAnchor.constraint(equalTo: pagingContainer.widthAnchor, multiplier: 1).isActive = true

               pageController.view.topAnchor.constraint(equalTo: pagingContainer.topAnchor).isActive = true
               pageController.view.bottomAnchor.constraint(equalTo: pagingContainer.bottomAnchor).isActive = true
               pageController.view.leadingAnchor.constraint(equalTo: pagingContainer.leadingAnchor).isActive = true
               pageController.view.trailingAnchor.constraint(equalTo: pagingContainer.trailingAnchor).isActive = true


        label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true


 label.bottomAnchor.constraint(equalTo: pagingContainer.topAnchor).isActive = true     
          }
       }
class SubContainerVC: UIViewController {

    var callback : (() -> Void)?

    let button: UIButton = {
        let button = UIButton()
        button.setTitle("Button!", for: .normal)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
        button.backgroundColor = .green
        return button
    }()

    @objc func buttonPressed(_ sender: UIButton) {
        print("Hello")
        //Pressing this button should increment the label on RootVC by one.
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemBlue
        view.addSubview(button)

        button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }

}
class PageViewController: UIPageViewController {

    lazy var subViewControllers:[UIViewController] = {
        return [SubContainerVC()]
    }()


    init(transitionStyle style:
        UIPageViewController.TransitionStyle, navigationOrientation: UIPageViewController.NavigationOrientation, options: [String : Any]? = nil) {
        super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
    }



    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()


        dataSource = self
        delegate = self
        setViewControllerFromIndex(index: 0)
    }

    func setViewControllerFromIndex(index:Int) {
        self.setViewControllers([subViewControllers[index]], direction: UIPageViewController.NavigationDirection.forward, animated: true, completion: nil)
    }
}

extension PageViewController: UIPageViewControllerDelegate, UIPageViewControllerDataSource {
    func presentationCount(for pageViewController: UIPageViewController) -> Int {
        return subViewControllers.count
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        let currentIndex:Int = subViewControllers.firstIndex(of: viewController) ?? 0
        if currentIndex <= 0 {
            return nil
        }
        return subViewControllers[currentIndex-1]
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        let currentIndex:Int = subViewControllers.firstIndex(of: viewController) ?? 0
        if currentIndex >= subViewControllers.count-1 {
            return nil
        }
        return subViewControllers[currentIndex+1]
    }
}
和PageViewController swift文件:

class RootVC: UIViewController {

    var tappedCount: Int = 0

    let pagingContainer: UIView = {
        let view = UIView()
        view.backgroundColor = .white
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    lazy var label: UILabel = {
        let label = UILabel()
        label.text = "\(tappedCount)"
        label.textAlignment = .center
        label.font = UIFont(name: "Copperplate", size: 90)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        view.addSubview(label)
        view.addSubview(pagingContainer)

        pagingContainer.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        pagingContainer.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1).isActive = true
        pagingContainer.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
        pagingContainer.heightAnchor.constraint(equalToConstant: 500).isActive = true

        let pageController = PageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
               addChild(pageController)
               pageController.didMove(toParent: self)
               pageController.view.translatesAutoresizingMaskIntoConstraints = false
               pagingContainer.addSubview(pageController.view)

               pageController.view.heightAnchor.constraint(equalTo: pagingContainer.heightAnchor, multiplier: 1).isActive = true
               pageController.view.widthAnchor.constraint(equalTo: pagingContainer.widthAnchor, multiplier: 1).isActive = true

               pageController.view.topAnchor.constraint(equalTo: pagingContainer.topAnchor).isActive = true
               pageController.view.bottomAnchor.constraint(equalTo: pagingContainer.bottomAnchor).isActive = true
               pageController.view.leadingAnchor.constraint(equalTo: pagingContainer.leadingAnchor).isActive = true
               pageController.view.trailingAnchor.constraint(equalTo: pagingContainer.trailingAnchor).isActive = true


        label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true


 label.bottomAnchor.constraint(equalTo: pagingContainer.topAnchor).isActive = true     
          }
       }
class SubContainerVC: UIViewController {

    var callback : (() -> Void)?

    let button: UIButton = {
        let button = UIButton()
        button.setTitle("Button!", for: .normal)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
        button.backgroundColor = .green
        return button
    }()

    @objc func buttonPressed(_ sender: UIButton) {
        print("Hello")
        //Pressing this button should increment the label on RootVC by one.
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemBlue
        view.addSubview(button)

        button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }

}
class PageViewController: UIPageViewController {

    lazy var subViewControllers:[UIViewController] = {
        return [SubContainerVC()]
    }()


    init(transitionStyle style:
        UIPageViewController.TransitionStyle, navigationOrientation: UIPageViewController.NavigationOrientation, options: [String : Any]? = nil) {
        super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
    }



    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()


        dataSource = self
        delegate = self
        setViewControllerFromIndex(index: 0)
    }

    func setViewControllerFromIndex(index:Int) {
        self.setViewControllers([subViewControllers[index]], direction: UIPageViewController.NavigationDirection.forward, animated: true, completion: nil)
    }
}

extension PageViewController: UIPageViewControllerDelegate, UIPageViewControllerDataSource {
    func presentationCount(for pageViewController: UIPageViewController) -> Int {
        return subViewControllers.count
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        let currentIndex:Int = subViewControllers.firstIndex(of: viewController) ?? 0
        if currentIndex <= 0 {
            return nil
        }
        return subViewControllers[currentIndex-1]
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        let currentIndex:Int = subViewControllers.firstIndex(of: viewController) ?? 0
        if currentIndex >= subViewControllers.count-1 {
            return nil
        }
        return subViewControllers[currentIndex+1]
    }
}
类PageViewController:UIPageViewController{
惰性var子视图控制器:[UIViewController]={
返回[subcainervc()]
}()
初始化(转换样式:
UIPageViewController.TransitionStyle,navigationOrientation:UIPageViewController.navigationOrientation,选项:[字符串:任意]?=nil){
super.init(transitionStyle:.滚动,navigationOrientation:.水平,选项:nil)
}
必需初始化?(编码器:NSCoder){
fatalError(“初始化(编码者:)尚未实现”)
}
重写func viewDidLoad(){
super.viewDidLoad()
数据源=self
代表=自我
setViewControllerFromIndex(索引:0)
}
func setViewControllerFromIndex(索引:Int){
self.setViewController([SubViewController[index]],方向:UIPageViewController.NavigationDirection.forward,动画:true,完成:nil)
}
}
扩展PageViewController:UIPageViewControllerDelegate,UIPageViewControllerDataSource{
func presentationCount(对于pageViewController:UIPageViewController)->Int{
返回subViewControllers.count
}
func pageViewController(uPageViewController:UIPageViewController,viewController在viewController:UIViewController之前)->UIViewController{
让currentIndex:Int=subViewControllers.firstIndex(of:viewController)??0
如果是currentIndex UIViewController{
让currentIndex:Int=subViewControllers.firstIndex(of:viewController)??0
如果currentIndex>=SubViewController.count-1{
归零
}
返回子视图控制器[currentIndex+1]
}
}

您可以向下游注入闭包到
Subcainervc
,这将导致上游执行闭包

大致如下(仅保留相关VC代码):

class subcainervc{
var buttonCallback:()->Void={}
@按下objc func按钮(\发送方:UIButton){
打印(“你好”)
buttonCallback()
}
}
类PageViewController:UIViewController{
//注意,对于惰性变量,不需要额外的闭包调用
lazy var subViewControllers=[subcainervc()]{
迪塞特{
//以防万一以后控制器可能会改变
subViewControllers.forEach{$0.buttonCallback=buttonCallback}
}
}
var buttonCallback:()->Void={}{
didSet{
subViewControllers.forEach{$0.buttonCallback=buttonCallback}
}
}
}
类RootVC:UIViewController{
var tappedCount:Int=0{
didSet{
label.text=“\(tappedCount)”
}
}
重写func viewDidLoad(){
super.viewDidLoad()
让pageController=PageViewController(转换样式:。滚动,导航方向:。水平)
//这将从PageViewController触发'didSet',从而
//在正在向下游传播的回调中
pageController.buttonCallback={self.tappedCount+=1}
}
}