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

问题描述

我试图在添加到情节提要编辑器中的容器视图中运行一个函数,但是当我在父视图控制器中调用函数时,没有任何反应。我希望能够调用一个函数并更改从父级触发的子级视图控制器的属性。我是在做错事还是应该以另一种方式做?

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
        }
    }
    
}

故事板: @L_502_0@

解决方法

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

当Container View加载嵌入式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?()
    }
    
}
,

我想您没有设置RouteSelectionViewController变量(顺便说一句,变量名应该以小写字母开头),所以它为nil,什么也没发生。

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