容器视图函数不在父视图中调用

Container view function not calling in parent view

我正在尝试 运行 我在故事板编辑器中添加的容器视图中的函数,但是当我在父视图控制器中调用它时,没有任何反应。我希望能够调用一个函数并更改从父级触发的子视图控制器的 属性。我是做错了什么还是应该换一种方式?

TLDR:从父级触发子视图控制器中的函数

父视图控制器:

//  ViewController.swift
import UIKit
class ViewController: UIViewController {

    @IBOutlet weak var routeConfirmationView: UIView! //This is the container view that I'm trying to work with
    var RouteSelectionViewController: RouteSelectionViewController?

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(routeConfirmationView)
        
        self?.RouteSelectionViewController?.getRidOfLoadingCover(isHidden: true) //The code that isn't doing anything
    }

}

容器视图控制器:

import UIKit

class RouteSelectionViewController: UIViewController {
    
    @IBOutlet weak var loadingCoverView: UIActivityIndicatorView!
    
    override func viewDidLoad() { 
        super.viewDidLoad(

    }
    //The function that I want to trigger from the other view controller:
    func getRidOfLoadingCover (isHidden: Bool){
        if (isHidden == true) {
            loadingCoverView.alpha = 0
        }
        else if (isHidden == false) {
            loadingCoverView.alpha = 100
        }
    }
    
}

故事板:

我猜你没有设置 RouteSelectionViewController 变量(顺便说一句,变量名应该以小写字母开头),所以它是 nil,没有任何反应。

如果您希望将一个视图控制器嵌入到另一个视图控制器中,您需要实现 视图控制器包含 要求(参见 documentation)。

要在容器视图中嵌入的视图控制器中调用函数或访问属性,您需要获取并保留对该控制器的引用。

当容器视图加载嵌入的 VC 时,它会调用 Prepare For Segue。在那里获取您的参考资料:

class WithContainerViewController: UIViewController {

    var routeSelectionVC: RouteSelectionViewController?

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? RouteSelectionViewController {
            // save reference to VC embedded in Container View
            self.routeSelectionVC = vc
        }
    }
    
    @IBAction func didTap(_ sender: Any) {
        if let vc = routeSelectionVC {
            vc.getRidOfLoadingCover(isHidden: true)
        }
    }
    
}

class RouteSelectionViewController: UIViewController {
    
    @IBOutlet weak var loadingCoverView: UIActivityIndicatorView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    //The function that I want to trigger from the other view controller:
    func getRidOfLoadingCover (isHidden: Bool){
        if (isHidden == true) {
            loadingCoverView.alpha = 0
        }
        else if (isHidden == false) {
            loadingCoverView.alpha = 100
        }
    }
    
}

接下来您可能会询问有关在“父”VC嵌入式VC.这可以通过协议/委托模式或闭包来完成。同样,您可以在准备 segue 时进行设置:

class WithContainerViewController: UIViewController {

    var routeSelectionVC: RouteSelectionViewController?

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? RouteSelectionViewController {
            // set the closure in the VC embedded in Container View
            vc.callbackClosure = {
                self.routeSelectionButtonTapped()
            }
            // save reference to VC embedded in Container View
            self.routeSelectionVC = vc
        }
    }

    @IBAction func didTap(_ sender: Any) {
        if let vc = routeSelectionVC {
            vc.getRidOfLoadingCover(isHidden: true)
        }
    }

    func routeSelectionButtonTapped() -> Void {
        print("Button in RouteSelectionViewController in Container View was tapped!")
    }

}

class RouteSelectionViewController: UIViewController {

    @IBOutlet weak var loadingCoverView: UIActivityIndicatorView!

    var callbackClosure: (() -> ())?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    //The function that I want to trigger from the other view controller:
    func getRidOfLoadingCover (isHidden: Bool){
        if (isHidden == true) {
            loadingCoverView.alpha = 0
        }
        else if (isHidden == false) {
            loadingCoverView.alpha = 100
        }
    }

    @IBAction func didTap(_ sender: Any) {
        callbackClosure?()
    }
    
}